Plaster

common-lisp
(ql:quickload '(usocket bordeaux-threads)) (defclass server () ((host :initform "127.0.0.1" :initarg :host :accessor host) (port :initform 1234 :initarg :port :accessor port) (clients :initform () :accessor clients))) (defmethod serve ((server server)) ;; Listen for incoming connections. (let ((server-socket (usocket:socket-listen (host server) (port server)))) (unwind-protect ;; Process each new client that connects. (loop do (process-connection server (usocket:socket-accept server-socket))) (usocket:socket-close server-socket)))) (defmethod process-connection ((server server) socket) (format T "~&New client: ~a~%" socket) (flet ((handler () ;; Read lines as long as the stream is open (loop with stream = (usocket:socket-stream socket) for line = (read-line stream NIL NIL) while line do (broadcast server line)))) (push socket (clients server)) (bt:make-thread #'handler :initial-bindings `((*standard-output* . ,*standard-output*))))) (defmethod broadcast ((server server) line) (dolist (socket (clients server)) (let ((stream (usocket:socket-stream socket))) (write-line line stream) (finish-output stream)))) (serve (make-instance 'server))

Annotations