(in-package #:live-chat-hunchentoot) (defvar *server* nil "The server acceptor.") (hunchentoot:define-easy-handler (chat-index :uri "/") () "Handle GET requests to / and render the chat UI." (render-chat-ui)) (hunchentoot:define-easy-handler (chat-handler :uri "/chat-messages") () "Handle GET requests to /chat-messages and render the chat UI." (render-chat-messages)) (hunchentoot:define-easy-handler (chat-post-handler :uri "/post-message" :default-request-type :post) () "Handle POST requests to /post-message and process the message." (let ((message (hunchentoot:post-parameter "message"))) (when (and message (not (string= message ""))) (handle-post-message message))) (render-chat-messages)) (defun start-chat-server (&optional (address "localhost") (port 8080)) "Start the Hunchentoot chat server." (setf (cl-who:html-mode) :html5 *server* (make-instance 'hunchentoot:easy-acceptor :address address :port port)) (hunchentoot:start *server*) (format t "Chat server started on port 8080~%") (wait-for-hunchentoot-listener "hunchentoot-listener-")) ;; https://stackoverflow.com/a/30424968 (defun wait-for-hunchentoot-listener (name) (bt2:join-thread (find-if (lambda (th) (prefixp name (bt2:thread-name th))) (bt2:all-threads)))) ;; https://github.com/brown/base?tab=readme-ov-file#prefixp-prefix-sequence-key-test-eql (defun prefixp (prefix sequence &key (test #'eql)) "Does PREFIX match a prefix of SEQUENCE?" (let ((mismatch (mismatch prefix sequence :test test))) (or (null mismatch) (= mismatch (length prefix)))))