Better error handling of connection loss
authorRaphaël Jakse <raphael.jakse@univ-grenoble-alpes.fr>
Sun, 5 Apr 2020 08:30:04 +0000 (10:30 +0200)
committerRaphaël Jakse <raphael.jakse@univ-grenoble-alpes.fr>
Sun, 5 Apr 2020 08:37:49 +0000 (10:37 +0200)
trivabble-server.js

index 504b21c85c13ea76c36b4675c930c19b15fb2a46..784f7964b8ef613174249bf500243b7663c45ff3 100644 (file)
@@ -145,12 +145,13 @@ function writeResponse(responseAndIsES, data, terminate) {
 function stopKeepAlive(responseAndIsES) {
     if (responseAndIsES.keepAliveTimeout) {
         clearTimeout(responseAndIsES.keepAliveTimeout);
+        responseAndIsES.keepAliveTimeout = 0;
     }
 }
 
 function keepAlive(responseAndIsES) {
     stopKeepAlive(responseAndIsES);
-    responseAndIsES.keepAliveTimeout = setTimeout(function () {
+    responseAndIsES.keepAliveTimeout = setTimeout(function keepAliveTimeout() {
         responseAndIsES[0].write(
             responseAndIsES[1]
                 ? ":\n\n"
@@ -260,14 +261,26 @@ Game.prototype.addListeningPlayer = function (playerName, responseAndIsES) {
     that.listeningPlayers.push(responseAndIsES);
     keepAlive(responseAndIsES);
 
-    responseAndIsES[0].on("close", function () {
+    var closed = false;
+
+    function close () {
+        if (closed) {
+            return;
+        }
+
+        closed = true;
         stopKeepAlive(responseAndIsES);
+
         var index = that.listeningPlayers.indexOf(responseAndIsES);
         if (index !== -1) {
             that.listeningPlayers[index] = that.listeningPlayers[that.listeningPlayers.length - 1];
             that.listeningPlayers.pop();
         }
-    });
+    }
+
+    responseAndIsES[0].on("close", close);
+    responseAndIsES[0].on("finish", close);
+    responseAndIsES[0].on("prefinish", close);
 
     this.playerJoined(playerName);
     this.commit();
@@ -690,6 +703,12 @@ function handleCommands(cmds, responseAndIsES) {
 
 function handleRequest(request, response) {
     var post = "";
+    var responseAndIsES = [response, false];
+
+    response.on("error", function (e) {
+        console.error("An error occurred while trying to write on a socket", e);
+        stopKeepAlive(responseAndIsES);
+    });
 
     // Thx http://stackoverflow.com/questions/4295782/how-do-you-extract-post-data-in-node-js
     request.on("data", function (data) {
@@ -746,21 +765,20 @@ function handleRequest(request, response) {
             return;
         }
 
-        var isEventSource = false;
         var eventSourceMatch = request.url.match(/\/:[^/]+\/sse\/(?<data>[\s\S]+)$/u);
 
         if (eventSourceMatch) {
             response.setHeader("Content-Type", "text/event-stream");
             post = decodeURIComponent(eventSourceMatch.groups.data);
-            isEventSource = true;
+            responseAndIsES[1] = true;
         } else {
             response.setHeader("Content-Type",   "text/plain");
             response.setHeader("Transfer-Encoding", "chunked");
         }
 
         dateNow = Date.now();
-        debuglog("RECEIVED", request.url, post, isEventSource);
-        handleCommands(post && JSON.parse(post), [response, isEventSource]);
+        debuglog("RECEIVED", request.url, post, responseAndIsES[1]);
+        handleCommands(post && JSON.parse(post), responseAndIsES);
     });
 }