IE, Chrome, Firefox plugins: gracefully disconnect when server connection drops.
1) Plugins fails gracefully in the face of a disconnect, returning undefined instead of making lots of noise.
2) Plugins invokes hosted.html's __gwt_disconnected() method the first time the session is detected as dropped. This glasspanels the app.
Review by: jat
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@7129 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/plugins/common/HostChannel.cpp b/plugins/common/HostChannel.cpp
index 90552a4..bff1b21 100644
--- a/plugins/common/HostChannel.cpp
+++ b/plugins/common/HostChannel.cpp
@@ -68,6 +68,7 @@
bool HostChannel::init(SessionHandler* handler, int minProtoVers,
int maxProtoVers, const std::string& hostedHtmlVers) {
+ this->handler = handler;
Debug::log(Debug::Debugging)
<< " negotiating versions - we support protocol " << minProtoVers
<< " through " << maxProtoVers << ", hostedHtmlVersion=" << hostedHtmlVers
diff --git a/plugins/common/HostChannel.h b/plugins/common/HostChannel.h
index f104d63..3c5c5e3 100644
--- a/plugins/common/HostChannel.h
+++ b/plugins/common/HostChannel.h
@@ -33,6 +33,7 @@
class HostChannel {
Socket sock;
static ByteOrder byteOrder;
+ SessionHandler* handler;
public:
~HostChannel() {
@@ -95,10 +96,12 @@
bool readByte(char& data) {
if (!isConnected()) {
+ handler->disconnectDetected();
return false;
}
int c = sock.readByte();
if (c < 0) {
+ handler->disconnectDetected();
return false;
}
data = static_cast<char>(c);
@@ -107,9 +110,14 @@
bool sendByte(const char data) {
if (!isConnected()) {
+ handler->disconnectDetected();
return false;
}
- return sock.writeByte(data);
+ if (!sock.writeByte(data)) {
+ handler->disconnectDetected();
+ return false;
+ }
+ return true;
}
bool readStringLength(uint32_t& data);
@@ -133,7 +141,15 @@
}
bool flush() {
- return sock.flush();
+ if (!sock.isConnected()) {
+ handler->disconnectDetected();
+ return false;
+ }
+ if (!sock.flush()) {
+ handler->disconnectDetected();
+ return false;
+ }
+ return true;
}
ReturnMessage* reactToMessagesWhileWaitingForReturn(SessionHandler* handler) {
diff --git a/plugins/common/SessionHandler.h b/plugins/common/SessionHandler.h
index 2cb011f..aebd00d 100644
--- a/plugins/common/SessionHandler.h
+++ b/plugins/common/SessionHandler.h
@@ -49,6 +49,24 @@
SetProperty = SPECIAL_SET_PROPERTY
};
protected:
+ SessionHandler(): alreadyDisconnected(false) {
+ }
+
+ /**
+ * Called by the server socket when it cannot read, write, or flush.
+ */
+ void disconnectDetected() {
+ if (!alreadyDisconnected) {
+ alreadyDisconnected = true;
+ disconnectDetectedImpl();
+ }
+ }
+
+ /**
+ * Implementors should invoke __gwt_disconnected() in the hosted.html window
+ * to "glass" the screen with a disconnect message.
+ */
+ virtual void disconnectDetectedImpl() = 0;
/**
* Report a fatal error -- the channel will be closed after this method
@@ -84,6 +102,9 @@
virtual void sendFreeValues(HostChannel& channel) = 0;
virtual ~SessionHandler() {}
+
+private:
+ bool alreadyDisconnected;
};
#endif