[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] 78/119: hold
From: |
Eric Schulte |
Subject: |
[elpa] 78/119: hold |
Date: |
Mon, 10 Mar 2014 16:57:43 +0000 |
eschulte pushed a commit to branch master
in repository elpa.
commit 7690987038d0f5640df8d704dfb66eff10a2fc33
Author: Eric Schulte <address@hidden>
Date: Tue Jan 7 01:36:44 2014 -0700
hold
---
examples/9-web-socket.el | 23 +++----------
web-server.el | 78 +++++++++++++++++++++++++++++++---------------
2 files changed, 59 insertions(+), 42 deletions(-)
diff --git a/examples/9-web-socket.el b/examples/9-web-socket.el
index 25408d6..3b39568 100644
--- a/examples/9-web-socket.el
+++ b/examples/9-web-socket.el
@@ -8,7 +8,7 @@ function connect(){
ws = new WebSocket(\"ws://localhost:9999/\");
ws.onopen = function() { alert(\"connected\"); };
- ws.onmessage = function(msg) { alert(msg.data); };
+ ws.onmessage = function(msg) { alert(\"Server: \" + msg.data); };
ws.onclose = function() { alert(\"connection closed\"); };
}
@@ -26,21 +26,10 @@ function close(){ ws.close(); };
(defun web-socket-server (request)
(with-slots (process headers) request
- (message "hd:%S" headers)
- (cond
- ((assoc :SEC-WEBSOCKET-KEY headers)
- (ws-response-header process 101
- (cons "Upgrade" "websocket")
- (cons "Connection" "upgrade")
- (cons "Sec-WebSocket-Accept"
- (ws-web-socket-handshake
- (cdr (assoc :SEC-WEBSOCKET-KEY headers)))))
- (set-process-plist process (list :parsed "" :pending nil :active nil))
- (set-process-coding-system process 'binary)
- (set-process-filter process 'ws-web-socket-filter)
- :keep-alive)
- (t
- (ws-response-header process 200 '("Content-type" . "text/html"))
- (process-send-string process web-socket-page)))))
+ (ws/web-socket-messages-do headers message
+ ;; (ws/web-socket-send message)
+ (message "GOT:%S" message))
+ (ws-response-header process 200 '("Content-type" . "text/html"))
+ (process-send-string process web-socket-page)))
(ws-start '(((:GET . ".*") . web-socket-server)) 9999)
diff --git a/web-server.el b/web-server.el
index f4729e1..e765be9 100644
--- a/web-server.el
+++ b/web-server.el
@@ -305,6 +305,29 @@ Return non-nil only when parsing is complete."
;;; Web Socket
+(defvar ws/web-socket-handler nil
+ "Function to handle web-socket messages, should take a single argument.")
+
+(defun int-to-bits (int size)
+ (let ((result (make-bool-vector size nil)))
+ (mapc (lambda (place)
+ (let ((val (expt 2 place)))
+ (when (>= int val)
+ (setq int (- int val))
+ (aset result place t))))
+ (reverse (number-sequence 0 (- size 1))))
+ (reverse (coerce result 'list))))
+
+(defun bits-to-int (bits)
+ (let ((place 0))
+ (reduce #'+ (mapcar (lambda (bit)
+ (prog1 (if bit (expt 2 place) 0) (incf place)))
+ (reverse bits)))))
+
+(defun ws/web-socket-mask (masking-key data)
+ (let ((masking-data (apply #'concat (make-list (+ 1 (/ (length data) 4))
+ masking-key))))
+ (apply #'string (cl-mapcar #'logxor masking-data data))))
;; Binary framing protocol
;; from http://tools.ietf.org/html/rfc6455#section-5.2
@@ -328,27 +351,6 @@ Return non-nil only when parsing is complete."
;; | Payload Data continued ... |
;; +---------------------------------------------------------------+
;;
-(defun int-to-bits (int size)
- (let ((result (make-bool-vector size nil)))
- (mapc (lambda (place)
- (let ((val (expt 2 place)))
- (when (>= int val)
- (setq int (- int val))
- (aset result place t))))
- (reverse (number-sequence 0 (- size 1))))
- (reverse (coerce result 'list))))
-
-(defun bits-to-int (bits)
- (let ((place 0))
- (reduce #'+ (mapcar (lambda (bit)
- (prog1 (if bit (expt 2 place) 0) (incf place)))
- (reverse bits)))))
-
-(defun ws/web-socket-mask (masking-key data)
- (let ((masking-data (apply #'concat (make-list (+ 1 (/ (length data) 4))
- masking-key))))
- (apply #'string (cl-mapcar #'logxor masking-data data))))
-
(defun ws-web-socket-filter (proc string)
"Web socket filter to pass whole frames to the client.
See RFC6455."
@@ -404,17 +406,43 @@ See RFC6455."
;; set to inactive
(set-process-plist proc (plist-put (process-plist proc) :active nil))
(if fin
- ;; call the web-socket handler
- (message "received message %S" data)
+ (funcall ws/web-socket-handler data) ; call the web-socket
handler
;; add parsed data to the process plist
(let ((plist (process-plist proc)))
(set-process-plist
(plist-put plist :parsed (concat (plist-get plist :parsed)
data))))
- ;; possibly parse pending input
+ ;; add any remaining un-parsed network data to pending
+ (when (< (+ index pl) (length string))
+ (let ((plist (process-plist proc)))
+ (set-process-plist
+ (plist-put plist :pending
+ (concat (substring string (+ index pl))
+ (or (plist-get plist :pending) ""))))))
+ ;; possibly re-parse any pending input
(when (plist-get (process-plist proc) :pending)
+ (set-process-plist (plist-put (process-plist proc) :pending nil))
(ws-web-socket-filter
- proc (plist-get (process-plist proc) :pending)))))))))
+ proc (plist-get (process-plist proc) :pending)))
+ nil))))))
+
+(defmacro ws/web-socket-messages-do (headers variable body)
+ "Helper macro to set the `ws-web-socket-filter' appropriately."
+ `(when (assoc :SEC-WEBSOCKET-KEY ,(identity headers))
+ (ws-response-header process 101
+ (cons "Upgrade" "websocket")
+ (cons "Connection" "upgrade")
+ (cons "Sec-WebSocket-Accept"
+ (ws-web-socket-handshake
+ (cdr (assoc :SEC-WEBSOCKET-KEY headers)))))
+ (set-process-plist process (list :parsed "" :pending nil :active nil))
+ (set-process-coding-system process 'binary)
+ (lexical-let ((ws/web-socket-handler (lambda ,(list variable) ,@body)))
+ (set-process-filter process 'ws-web-socket-filter))
+ (throw 'close-connection :keep-alive)))
+
+(defun ws/web-socket-send (string)
+ )
;;; Convenience functions to write responses
- [elpa] 70/119: run all tests with "make check", (continued)
- [elpa] 70/119: run all tests with "make check", Eric Schulte, 2014/03/10
- [elpa] 67/119: test large file upload (w/o network chunking), Eric Schulte, 2014/03/10
- [elpa] 69/119: refactoring no multiple concurrent header parsing, Eric Schulte, 2014/03/10
- [elpa] 71/119: updating notes and README text, Eric Schulte, 2014/03/10
- [elpa] 72/119: notes for running behind an Apache HTTPS proxy, Eric Schulte, 2014/03/10
- [elpa] 73/119: some more examples to implement, Eric Schulte, 2014/03/10
- [elpa] 68/119: no multiple concurrent entry of ws-parse-request, Eric Schulte, 2014/03/10
- [elpa] 76/119: and more web-socket progress, Eric Schulte, 2014/03/10
- [elpa] 74/119: beginning to implement web-socket support, Eric Schulte, 2014/03/10
- [elpa] 77/119: handle chunked receipt of web-socket messages, Eric Schulte, 2014/03/10
- [elpa] 78/119: hold,
Eric Schulte <=
- [elpa] 79/119: beginning to add convenience macro for web sockets, Eric Schulte, 2014/03/10
- [elpa] 81/119: implemented ws-web-socket-frame to send replies, Eric Schulte, 2014/03/10
- [elpa] 80/119: helpers for handling web socket connections, Eric Schulte, 2014/03/10
- [elpa] 82/119: web-sockets are working, Eric Schulte, 2014/03/10
- [elpa] 84/119: more examples, Eric Schulte, 2014/03/10
- [elpa] 85/119: renaming example files, Eric Schulte, 2014/03/10
- [elpa] 86/119: another example idea -- org export service, Eric Schulte, 2014/03/10
- [elpa] 87/119: update server stopping w/requests process field, Eric Schulte, 2014/03/10
- [elpa] 83/119: supports web sockets, Eric Schulte, 2014/03/10
- [elpa] 75/119: more web-socket implementation, Eric Schulte, 2014/03/10