mmo-project/lisp/server/server.lisp

53 lines
1.8 KiB
Common Lisp

(load "~/quicklisp/setup.lisp")
(ql:quickload '(:clack :websocket-driver :cl-bcrypt :datafly :sxql :alexandria :com.inuoe.jzon))
(defpackage :mmo-server
(:use :common-lisp :clack :websocket-driver :cl-bcrypt :datafly :sxql :alexandria :com.inuoe.jzon))
(in-package :mmo-server)
(defvar *connections* (make-hash-table))
(defun handle-new-connection (con)
(setq *user* (format nil "{\"cmd\":\"login\", \"uid\":\"~a\"}" (random 100000)))
(setf (gethash con *connections*)
*user*)
(websocket-driver:send con *user*))
(defun broadcast-to-room (connection json)
(setq message (com.inuoe.jzon:parse json))
(loop :for con :being :the :hash-key :of *connections* :do
(websocket-driver:send con json)))
(defun handle-close-connection (connection)
(let ((message (format nil "{\"cmd\":\"logout\", \"user\":\"~a\"}"
(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 :close ws
(lambda (&key code reason)
(declare (ignore code reason))
(handle-close-connection ws)))
(websocket-driver:on :error ws
(lambda (error)
(format t "Got an error: ~S~%" error)))
(lambda (responder)
(declare (ignore responder))
(websocket-driver:start-connection ws))))
(defvar *chat-handler* (clack:clackup #'chat-server :port 12345))