(ql:quickload :cl-ppcre) (ql:quickload :base64) (ql:quickload :sha1) (ql:quickload :flexi-streams) (ql:quickload :usocket) (use-package :cl-ppcre) (use-package :sb-bsd-sockets) (use-package :sb-thread) (defparameter *address* #(0 0 0 0)) (defparameter *port* 9990) (defparameter *server* nil) (defparameter *clients* nil) (defparameter *connection* nil) (defparameter *errors* nil) (load "./http.lisp") (load "./common.lisp") (defparameter *websockts* nil) (defun on-message (message) (let* ((words (cl-ppcre:split #/\s+/# message)) (get? (string= (first words) "GET")) (path (second words)) (websocket (second (multiple-value-list (scan-to-strings "Sec-WebSocket-Key: (.*)" message))))) ($output "~A~%~A~%path: ~A" *connection* (replace-string message (coerce (list #\Return) 'string) "") path) (cond (get? (cond ((string= path "/favicon.ico") (princ "Not Found") ([send] (not-found)) (close *connection*) ) (websocket (push *connection* *websockts*) ( (connect-websocket (elt websocket 0)))) (:default ;; Parse the path ([send] (http (second words))) ;; (socket-close *connection*) ;; ( message) ))) (:else ($output "Not HTTP: ~A" message) ;; ( message) )))) (defun on-leave () ( (fmt ">> [~A] has left... <<~%" (sb-bsd-sockets::socket-peerstring *connection*)))) (defun on-connected (*connection* &aux data (online t)) ;; ( (fmt "~%Welcome [~A]~%" *connection*)) ($output "Connected...~A" *connection*) (while (and online (setf data (trim (@receive)))) (cond ((equalp data ":exit") (on-leave) ($output "<> ~A ~%" *connection*) (clear) (close *connection*) (setf online nil)) ((> (length data) 0) (on-message data)) (:else ($output "Goodbye ~A" *connection*) (close *connection*) (setf online nil))))) ;; (socket-close connection))) (defun start-server (&optional (port *port*)) (setf *server* (make-instance 'inet-socket :type :stream :protocol :tcp)) (setf *clients* nil) (setf (sockopt-reuse-address *server*) t) ;; (setf (non-blocking-mode *server*) t) (socket-bind *server* *address* port) (socket-listen *server* 100) ;backlog (format t "~&Listening :~A~%" port) (make-thread λ(loop (multiple-value-bind (inet-socket peer) (socket-accept *server*) (let1 (*connection* (socket-make-stream inet-socket :input t :output t)) ($output "[[ Stream Coming::~A ]]~%" peer) (push *connection* *clients*) (make-thread #'on-connected :arguments (list *connection*))))))) (defun create-server (port) (let* ((socket (usocket:socket-connect nil nil :protocol :datagram :element-type '(unsigned-byte 8) :local-host "127.0.0.1" :local-port port)) (buffer (make-array 1024 :element-type '(unsigned-byte 8)))) (sb-thread:make-thread λ(loop (multiple-value-bind (buffer size client receive-port) (usocket:socket-receive socket buffer nil) ($output "~A size: ~A host: ~A port: ~A~%~A" buffer size client receive-port (flexi-streams:octets-to-string (subseq buffer 0 size))) (usocket:socket-send socket (reverse buffer) size :port receive-port :host client)))) ;; (usocket:socket-close socket) )) (defun create-client (port) (let ((socket (usocket:socket-connect "127.0.0.1" port :protocol :datagram :element-type '(unsigned-byte 8))) (buffer (make-array 1024 :element-type '(unsigned-byte 8)))) (sb-thread:make-thread (^() (usocket:socket-receive socket buffer 1024) (format t "Receive: ~A~%" buffer))) (loop (usocket:socket-send socket (read-line) nil)) (usocket:socket-close socket)))