diff --git a/etherpad.el b/etherpad.el index a63f501..8684c61 100644 --- a/etherpad.el +++ b/etherpad.el @@ -80,13 +80,16 @@ (defvar etherpad--local-pad-revision "" "Buffer local pad details.") -;; minor mode + (define-minor-mode etherpad-mode - "Minor mode to sync changes with etherpad." nil " etherpad" nil + "Minor mode to sync changes with etherpad." + :lighter " etherpad" + :keymap (make-sparse-keymap) (if etherpad-mode (ethersync--add-change-hooks) (ethersync--remove-change-hooks))) + ;; API functions (defun etherpad-openapi () diff --git a/ethersync.el b/ethersync.el index f6b4700..ac5ea39 100644 --- a/ethersync.el +++ b/ethersync.el @@ -37,7 +37,7 @@ ;; details -> https://etherpad.org/doc/v1.8.5/#index_http_api ;; current issues 2020-12-15 00:52:32 -;; - on ws per buffer. buffer local. shared. +;; - one ws per buffer. buffer local. shared. ;; - incorrect newline counts when sending changesets ;; - problems w. deleting text and/or changing buffer size & change-hooks ;; - see "Additional Constraints" of easysync @@ -70,28 +70,50 @@ (defvar-local ep--hearbeat-timer nil) (defvar-local ep--current-socket nil) -;; enable/disable keep alive message to the server -(defun ethersync-heartbeat-start () - "Maintain connection to server with periodic pings." - (message "heartbeat started: %s" (current-buffer)) - (setq ep--hearbeat-timer - (run-with-timer 5 15 #'wss-send "2"))) - -(defun ethersync-heartbeat-stop () - "Stop sending keep-alive messages." - (cancel-timer ep--hearbeat-timer)) ;; buffering (defvar *etherpad-buffer* (generate-new-buffer "*etherpad*")) +;; keep-alive message & heartbeat timers + +(defun ethersync-heartbeat-send () + "Send a keep-alive message." + ;; only send if there is a current socket + ;; and delete an active timer when there isn't a socket open + (message "heartbeat? %s" (ethersync-current-socket)) + (when (ethersync-current-socket) + (wss-send "2") + (message "heartbeat sent: %s" *etherpad-buffer*)) + (when (not (ethersync-current-socket)) + (ethersync-heartbeat-stop) + (message "heartbeat stopped: %s" ep--hearbeat-timer))) + +(defun ethersync-heartbeat-start () + "Maintain connection to server with periodic pings." + (message "heartbeat started: %s" *etherpad-buffer*) + (setq ep--hearbeat-timer + (run-with-timer 5 15 #'ethersync-heartbeat-send)) + (ethersync-current-socket)) + +(defun ethersync-heartbeat-stop () + "Stop sending keep-alive messages." + (when ep--hearbeat-timer + (cancel-timer ep--hearbeat-timer)) + (setq ep--hearbeat-timer nil) + (message "heartbeat stopped: %s" *etherpad-buffer*)) + + +;; sockets + (defun ethersync-current-socket (&optional socket) "Return currently active socket or set SOCKET as current." - (message "socket in buffer: %s" (current-buffer)) - (if socket - (setq ep--current-socket socket) - ep--current-socket)) + (when socket + (setq ep--current-socket socket)) + (message "current socket: %s in buffer: %s" ep--current-socket *etherpad-buffer*)) + ;; setters + (defun ethersync--set-local-rev (n) "Set the local revision." (message "current rev: %s" ep--local-rev) @@ -382,9 +404,11 @@ Numeric offsets are calculated from the beginning of the buffer." (defun ethersync-wss-send (msg) "Send MSG to a websocket." - (when (stringp msg) - (websocket-send-text - (ethersync-current-socket) msg))) + (if (websocket-openp (ethersync-current-socket)) + (when (stringp msg) + (websocket-send-text + (ethersync-current-socket) msg)) + (message "websocket is closed. not sending: %s" msg))) ;; parsing & dispatch of incoming frames diff --git a/notes/etherpad-protocol.org b/notes/etherpad-protocol.org index 0409665..495ef0a 100644 --- a/notes/etherpad-protocol.org +++ b/notes/etherpad-protocol.org @@ -16,7 +16,7 @@ possibly relevant parts of the etherpad code - https://github.com/ether/etherpad-lite/blob/develop/src/node/handler/PadMessageHandler.js - https://github.com/payload/ethersync/blob/master/src/ethersync.coffee - - code for a [[https://github.com/JohnMcLear/etherpad-cli-client/blob/master/lib/index.js][cli-client]] and the [[https://github.com/ether/etherpad-lite/tree/develop/src/static/js][javasctipt client]] + - code for a [[https://github.com/JohnMcLear/etherpad-cli-client/blob/master/lib/index.js][cli-client]] and the [[https://github.com/ether/etherpad-lite/tree/develop/src/static/js][javascript client]] * websockets & socket.io @@ -39,7 +39,7 @@ browser client sends url with pad name to server (e.g. https://etherpad.wikimed client -> ep_server: wss://example.org//socket.io/?EIO=3&transport=websocket ep_server --> client: 0 sid, upgrades, etc client -> ep_server: 2 CLIENT_READY padId, token, etc -ep_server --> client: 42 CLIENT_VARS pad text, lots of junk about server, colours, authors, etc +ep_server --> client: 42 CLIENT_VARS pad text, lots of detail about server, colours, authors, etc ep_server --> client: 42 USER_NEWINFO (if other active clients) == local edits == @@ -466,3 +466,77 @@ example/reduced < 40 > #+END_SRC + +#+BEGIN_SRC js +[ + "message", + { + "type": "COLLABROOM", + "data": { + "type": "NEW_CHANGES", + "newRev": 969, + "changeset": "Z:2r>2*0=1=5*1|1+1*1*2*3*4*5+1|1=1*6=1|1=4*7=1|1=4*8=1|1=a*9=1|1=5*0=1|1=f*0=1|1=q*5=1|1=4*6=1|1=4*7=1|1=4*8=1$\n*", + "apool": { + "numToAttrib": { + "0": [ + "start", + "1" + ], + "1": [ + "author", + "a.TA0tvO487Oh304Up" + ], + "2": [ + "insertorder", + "first" + ], + "3": [ + "list", + "number1" + ], + "4": [ + "lmkr", + "1" + ], + "5": [ + "start", + "2" + ], + "6": [ + "start", + "3" + ], + "7": [ + "start", + "4" + ], + "8": [ + "start", + "5" + ], + "9": [ + "start", + "6" + ] + }, + "attribToNum": { + "start,1": 0, + "author,a.TA0tvO487Oh304Up": 1, + "insertorder,first": 2, + "list,number1": 3, + "lmkr,1": 4, + "start,2": 5, + "start,3": 6, + "start,4": 7, + "start,5": 8, + "start,6": 9 + }, + "nextNum": 10 + }, + "author": "a.TA0tvO487Oh304Up", + "currentTime": 1638017098574, + "timeDelta": 8923 + } + } +] +#+END_SRC