(define-symbol-macro (receive)) (define-symbol-macro @cc (car *clients*)) (define-symbol-macro @ee (car *errors*)) (defun clear () (setf *clients* (=> (delete *connection* *clients*) (delete-if λ(= -1 (socket-file-descriptor _)) ~)))) (defun (&rest rest) (apply #'socket-send *connection* (append rest '(nil)))) (defun [send] (text) (write-string text *connection*) (force-output *connection*)) (defun (text &aux (sender *connection*)) (dolist (client *clients*) (cond ((equal client sender) (handler-case ;; (apply #' (fmt "[self] ~A~%" text) rest) ([send] (fmt "[self] ~A~%" text)) (error (c) ($error "Send to self fail?? ~%~A" c)))) (:others (let1 (*connection* client) (sleep 2) (handler-case ([send] (fmt "~A ~A~%" (or (sb-bsd-sockets::socket-peerstring sender) :[server]) text)) (error (c) ;; (clear) ($error "BroaOooops [~A]~%" c)))))))) (defun (text &aux (sender *connection*)) (dolist (client (remove-if λ(eql sender _) *clients*)) (let1 (*connection* client) (handler-case ([send] (fmt "[~A ~A]:~%~A~%" (or (sb-bsd-sockets::socket-peerstring sender) :server) (now) text)) (error (c) ;; (clear) ($error "Oooops [~A]~%" c)))))) (defparameter *cache* (make-array 50 :initial-element nil)) ;; get-output-stream-string ;; (make-string-output-stream) (defun @receive () (vprint *connection*) (with-output-to-string (*standard-output*) (loop ;; (sleep 0.3) (let1 (string (ignore-errors (read-line *connection* nil ""))) ;; (format *error-output* "@receive [~A] ~%" string) (princ string) (princ #\Newline) (when (<= (length string) 1) (return)))))) (defun receive (&aux (max 51024)) "Read data from a connection." (multiple-value-bind (buffer len peer) (handler-case (progn (socket-receive *connection* nil max :element-type '(unsigned-byte 8))) (error (c) ($error "Receive Error: ~A ~S~&" c *connection*) (push (list c *connection*) *errors*) (values (socket-file-descriptor *connection*) -1))) (declare (ignore peer)) (vprint (socket-file-descriptor *connection*) len) (cond ((= len -1) (socket-close *connection*)) ((= len 0) ($error "## Closed ## ~A ~%" *connection*) (socket-close *connection*) (clear) (sleep 1)) (:otherwise (setf buffer (flexi-streams:octets-to-string (subseq buffer 0 len)))))))