You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by kp...@apache.org on 2013/10/10 00:55:32 UTC

svn commit: r1530822 - /tomcat/trunk/webapps/examples/websocket/drawboard.xhtml

Author: kpreisser
Date: Wed Oct  9 22:55:31 2013
New Revision: 1530822

URL: http://svn.apache.org/r1530822
Log:
Fix bug in the drawboard JavaScript when socket.onmessage is raised while the Image.load event from a previous message did not yet raise which caused messages to be ignored.

Modified:
    tomcat/trunk/webapps/examples/websocket/drawboard.xhtml

Modified: tomcat/trunk/webapps/examples/websocket/drawboard.xhtml
URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/examples/websocket/drawboard.xhtml?rev=1530822&r1=1530821&r2=1530822&view=diff
==============================================================================
--- tomcat/trunk/webapps/examples/websocket/drawboard.xhtml (original)
+++ tomcat/trunk/webapps/examples/websocket/drawboard.xhtml Wed Oct  9 22:55:31 2013
@@ -106,6 +106,53 @@
 
             function Room(drawContainer) {
 
+                /* A pausable message handler that can be used for
+                 * the WebSocket's onmessage event (e.g. when we need to wait
+                 * for a Image's load event before we can process further
+                 * WebSocket messages).
+                 * The object's handleMessageInternal(message) method
+                 * should be called from socket.onmessage.
+                 * The object's messageHandler should be set to the
+                 * function which is actually processing the message.
+                 * Call pauseMessageProcessing() to pause processing and
+                 * resumeMessageProcessing() to resume it.
+                 */
+                function PausableMessageHandler() {
+
+                    var pauseMessageProcessing = false;
+                    // Queue for buffering incoming messages until they
+                    // can be processed.
+                    var messageQueue = [];
+
+
+                    this.messageHandler = function(message) { };
+
+                    this.handleMessageInternal = function(message) {
+                        // If message processing is paused, we push it
+                        // into the queue - otherwise we process it directly.
+                        if (pauseMessageProcessing) {
+                            messageQueue.push(message);
+                        } else {
+                            this.messageHandler(message);
+                        }
+                    };
+
+                    this.pauseMessageProcessing = function() {
+                        pauseMessageProcessing = true;
+                    };
+
+                    this.resumeMessageProcessing = function() {
+                        pauseMessageProcessing = false;
+
+                        // Process all queued messages until some handler calls 
+                        // pauseMessageProcessing() again.
+                        while (messageQueue.length > 0 && !pauseMessageProcessing) {
+                            var msg = messageQueue.pop();
+                            this.messageHandler(msg);
+                        }
+                    };
+                }
+
                 // The WebSocket object.
                 var socket;
                 // ID of the timer which sends ping messages.
@@ -207,6 +254,17 @@
                             + "/examples/websocket/drawboard";
                     socket = new WebSocket(host);
 
+                    /* If processing of messages should be paused.
+                     * This is needed when we load an Image object with data
+                     * from a previous message, because we must wait until the
+                     * Image's load event it raised before we can use it (and
+                     * in the meantime the socket.message event could be
+                     * raised).
+                     * Therefore we need to use a pausable message handler
+                     * to handle the incoming messages.
+                     */
+                    var messageHandler = new PausableMessageHandler();
+
                     socket.onopen = function () {
                         // Socket has opened. Now wait for the server to
                         // send us the initial packet.
@@ -226,7 +284,7 @@
                         window.clearInterval(pingTimerId);
                     }
 
-                    socket.onmessage = function(message) {
+                    messageHandler.messageHandler = function(message) {
 
                         // Split joined message and process them
                         // invidividually.
@@ -259,10 +317,10 @@
                                         // message containing the room images
                                         // as PNG. Therefore we temporarily swap
                                         // the message handler.
-                                        var originalHandler = socket.onmessage;
-                                        socket.onmessage = function(message) {
+                                        var originalHandler = messageHandler.messageHandler;
+                                        messageHandler.messageHandler = function(message) {
                                             // First, we restore the original handler.
-                                            socket.onmessage = originalHandler;
+                                            messageHandler.messageHandler = originalHandler;
 
                                             // Read the image.
                                             var blob = message.data;
@@ -276,20 +334,16 @@
                                             // We must wait until the onload event is
                                             // raised until we can draw the image onto
                                             // the canvas.
-                                            
-                                            // TODO: I don't know if there is a guarantee
-                                            // that no WebSocket events (onmessage) will
-                                            // be raised until the onload event of this
-                                            // image is raised. Maybe we need to need to
-                                            // push websocket messages on a queue until
-                                            // this onload function is called.
+                                            // Therefore we need to pause the message
+                                            // handler until the image is loaded.
+                                            messageHandler.pauseMessageProcessing();
+
                                             img.onload = function() {
 
                                                 // Release the object URL.
                                                 URL.revokeObjectURL(url);
 
                                                 // Set the canvases to the correct size.
-            
                                                 for (var i = 0; i < canvasArray.length; i++) {
                                                     canvasArray[i].width = img.width;
                                                     canvasArray[i].height = img.height;
@@ -310,6 +364,10 @@
 
                                                 isStarted = true;
                                                 startControls();
+
+
+                                                // Finally, resume the message handler.
+                                                messageHandler.resumeMessageProcessing();
                                             };
 
                                             img.src = url;
@@ -375,8 +433,13 @@
                         }
                     };
 
+                    socket.onmessage = function(message) {
+                        messageHandler.handleMessageInternal(message);
+                    };
+
                 }
 
+
                 function refreshPlayerCount() {
                     labelPlayerCount.nodeValue = String(playerCount);
                 }



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org