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

This commit is contained in:
Michael Jumper committed 2017-02-08 20:19:11 -08:00
1 parent 7fd7035a47
commit 6ae9faddc2
2 files changed
+44 -1

No files matched your search

@@ -47,6 +47,14 @@ public class OutputStreamInterceptingFilter
private static final Logger logger =
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
@@ -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;