Repository: incubator-guacamole-client
Updated Branches:
  refs/heads/master 7fd7035a4 -> fa0746039


GUACAMOLE-201: Occasionally verify client responsiveness when intercepting 
streams.

Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/commit/6ae9fadd
Tree: 
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/tree/6ae9fadd
Diff: 
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/diff/6ae9fadd

Branch: refs/heads/master
Commit: 6ae9faddc2a0542e441522b3440685f036c18871
Parents: 7fd7035
Author: Michael Jumper <[email protected]>
Authored: Wed Feb 8 19:49:01 2017 -0800
Committer: Michael Jumper <[email protected]>
Committed: Wed Feb 8 20:19:11 2017 -0800

----------------------------------------------------------------------
 .../tunnel/OutputStreamInterceptingFilter.java  | 40 +++++++++++++++++++-
 .../webapp/app/rest/services/tunnelService.js   |  5 +++
 2 files changed, 44 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/6ae9fadd/guacamole/src/main/java/org/apache/guacamole/tunnel/OutputStreamInterceptingFilter.java
----------------------------------------------------------------------
diff --git 
a/guacamole/src/main/java/org/apache/guacamole/tunnel/OutputStreamInterceptingFilter.java
 
b/guacamole/src/main/java/org/apache/guacamole/tunnel/OutputStreamInterceptingFilter.java
index 7cdadba..f016906 100644
--- 
a/guacamole/src/main/java/org/apache/guacamole/tunnel/OutputStreamInterceptingFilter.java
+++ 
b/guacamole/src/main/java/org/apache/guacamole/tunnel/OutputStreamInterceptingFilter.java
@@ -48,6 +48,14 @@ public class OutputStreamInterceptingFilter
             LoggerFactory.getLogger(OutputStreamInterceptingFilter.class);
 
     /**
+     * Whether this OutputStreamInterceptingFilter should respond to received
+     * blobs with "ack" messages on behalf of the client. If false, blobs will
+     * still be handled by this filter, but empty blobs will be sent to the
+     * client, forcing the client to respond on its own.
+     */
+    private boolean acknowledgeBlobs = true;
+
+    /**
      * Creates a new OutputStreamInterceptingFilter which selectively 
intercepts
      * "blob" and "end" instructions. The required "ack" responses will
      * automatically be sent over the given tunnel.
@@ -129,10 +137,22 @@ public class OutputStreamInterceptingFilter
             return null;
         }
 
-        // Attempt to write data to stream
         try {
+
+            // Attempt to write data to stream
             stream.getStream().write(blob);
+
+            // Force client to respond with their own "ack" if we need to
+            // confirm that they are not falling behind with respect to the
+            // graphical session
+            if (!acknowledgeBlobs) {
+                acknowledgeBlobs = true;
+                return new GuacamoleInstruction("blob", index, "");
+            }
+
+            // Otherwise, acknowledge the blob on the client's behalf
             sendAck(index, "OK", GuacamoleStatus.SUCCESS);
+
         }
         catch (IOException e) {
             sendAck(index, "FAIL", GuacamoleStatus.SERVER_ERROR);
@@ -164,6 +184,17 @@ public class OutputStreamInterceptingFilter
 
     }
 
+    /**
+     * Handles a single "sync" instruction, updating internal tracking of
+     * client render state.
+     *
+     * @param instruction
+     *     The "sync" instruction being handled.
+     */
+    private void handleSync(GuacamoleInstruction instruction) {
+        acknowledgeBlobs = false;
+    }
+
     @Override
     public GuacamoleInstruction filter(GuacamoleInstruction instruction)
             throws GuacamoleException {
@@ -178,6 +209,13 @@ public class OutputStreamInterceptingFilter
             return instruction;
         }
 
+        // Monitor "sync" instructions to ensure the client does not starve
+        // from lack of graphical updates
+        if (instruction.getOpcode().equals("sync")) {
+            handleSync(instruction);
+            return instruction;
+        }
+
         // Pass instruction through untouched
         return instruction;
 

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/6ae9fadd/guacamole/src/main/webapp/app/rest/services/tunnelService.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/rest/services/tunnelService.js 
b/guacamole/src/main/webapp/app/rest/services/tunnelService.js
index 11c2e92..f74088d 100644
--- a/guacamole/src/main/webapp/app/rest/services/tunnelService.js
+++ b/guacamole/src/main/webapp/app/rest/services/tunnelService.js
@@ -215,6 +215,11 @@ angular.module('rest').factory('tunnelService', 
['$injector',
             document.body.removeChild(iframe);
         };
 
+        // Acknowledge (and ignore) any received blobs
+        stream.onblob = function acknowledgeData() {
+            stream.sendAck('OK', Guacamole.Status.Code.SUCCESS);
+        };
+
         // Automatically remove iframe from DOM a few seconds after the stream
         // ends, in the browser does NOT fire the "load" event for downloads
         stream.onend = function downloadComplete() {

Reply via email to