From a88367f527f6343edf4f0bb2d32ccfb5ec54e4d2 Mon Sep 17 00:00:00 2001 From: James Shore Date: Fri, 11 Aug 2017 14:06:03 -0700 Subject: [PATCH] Basic spike to remove ghost pointers after timeout --- src/server/real_time_server.js | 30 ++++++++++++++++++++++++++++++ todo.txt | 2 ++ 2 files changed, 32 insertions(+) diff --git a/src/server/real_time_server.js b/src/server/real_time_server.js index 238d14d45..a60587290 100644 --- a/src/server/real_time_server.js +++ b/src/server/real_time_server.js @@ -21,6 +21,7 @@ constructor() { this._socketIoConnections = {}; + this._clientTimeouts = {}; } start(httpServer) { @@ -30,6 +31,7 @@ trackSocketIoConnections(this._socketIoConnections, this._ioServer); handleSocketIoEvents(this, this._ioServer); + timeoutInactiveClients(this); this._httpServer.on("close", failFastIfHttpServerClosed); } @@ -55,10 +57,23 @@ }; + function timeoutInactiveClients(self) { + setInterval(() => { + const now = Date.now(); + Object.keys(self._clientTimeouts).forEach((clientId) => { + const clientLastActivity = self._clientTimeouts[clientId]; + if (now - clientLastActivity > 1000) { + broadcastAndStoreEvent(self, null, new ServerRemovePointerEvent(clientId)); + } + }); + }, 100); + } + function handleSocketIoEvents(self, ioServer) { ioServer.on("connect", (socket) => { replayPreviousEvents(self, socket); handleClientEvents(self, socket); + trackClientTimeouts(self, socket); socket.on("disconnect", () => { broadcastAndStoreEvent(self, socket, new ServerRemovePointerEvent(socket.id)); @@ -66,6 +81,21 @@ }); } + function trackClientTimeouts(self, socket) { + var clientId = socket.id; + refreshClientTimeout(self, socket); + socket.on(ClientPointerEvent.EVENT_NAME, () => { + refreshClientTimeout(self, socket); + }); + socket.on("disconnect", () => { + delete self._clientTimeouts[clientId]; + }); + } + + function refreshClientTimeout(self, socket) { + self._clientTimeouts[socket.id] = Date.now(); + } + function replayPreviousEvents(self, socket) { self._eventRepo.replay().forEach((event) => { socket.emit(event.name(), event.payload()); diff --git a/todo.txt b/todo.txt index c07543637..f3989e24b 100644 --- a/todo.txt +++ b/todo.txt @@ -31,6 +31,7 @@ User Stories to finish current MMF: - show disconnection warning / other UX when client is disconnected - handle server reset smoothly (clear the drawing? re-sync to browsers? not persistence/DB) - handle packet loss (What packet loss is possible? TCP handles this? What about unstable cellular connections?) + - at least handle glitches in Socket.IO where we don't receive a message - version synchronization across client/server - collision-handling / conflicts / race conditions @@ -53,6 +54,7 @@ User Stories to finish current MMF: Engineering Tasks: - +? Factor out domain logic from Socket.IO handling (in RealTimeServer) To Do on current task: - \ No newline at end of file