47 lines
1.7 KiB
Common Lisp
47 lines
1.7 KiB
Common Lisp
(load "~/quicklisp/setup.lisp")
|
|
(ql:quickload '(clack websocket-driver alexandria))
|
|
|
|
(defvar *connections* (make-hash-table))
|
|
|
|
(defun broadcast-to-room (connection message)
|
|
(let ((message (format nil "{\"uid\":\"~a\", \"msg\":~a}"
|
|
(gethash connection *connections*)
|
|
message)))
|
|
(loop :for con :being :the :hash-key :of *connections* :do
|
|
(websocket-driver:send con message))))
|
|
|
|
(defun handle-new-connection (con)
|
|
(let ((user (format nil "~a" (random 100000))))
|
|
(setf (gethash con *connections*) user)
|
|
(websocket-driver:send con (format nil "{\"uid\":\"~a\",\"msg\":{\"cmd\":\"login\"}}" user))))
|
|
|
|
(defun handle-close-connection (connection)
|
|
(let ((message (format nil "{ \"uid\":\"~a\",\"msg\":{\"cmd\":\"login\"}}"
|
|
(gethash connection *connections*))))
|
|
(remhash connection *connections*)
|
|
(loop :for con :being :the :hash-key :of *connections* :do
|
|
(websocket-driver:send con message))))
|
|
|
|
(defun chat-server (env)
|
|
(let ((ws (websocket-driver:make-server env)))
|
|
(websocket-driver:on :open ws
|
|
(lambda () (handle-new-connection ws)))
|
|
|
|
(websocket-driver:on :message ws
|
|
(lambda (msg)
|
|
(broadcast-to-room ws msg)))
|
|
|
|
(websocket-driver:on :error ws
|
|
(lambda (msg)
|
|
(format t "~a" msg)))
|
|
|
|
(websocket-driver:on :close ws
|
|
(lambda (&key code reason)
|
|
(declare (ignore code reason))
|
|
(handle-close-connection ws)))
|
|
(lambda (responder)
|
|
(declare (ignore responder))
|
|
(websocket-driver:start-connection ws))))
|
|
|
|
(defvar *chat-handler* (clack:clackup #'chat-server :port 5000))
|