summaryrefslogtreecommitdiffstats
path: root/server/src
diff options
context:
space:
mode:
authorLeif Åstrand <leif@vaadin.com>2013-04-18 12:35:10 +0300
committerVaadin Code Review <review@vaadin.com>2013-04-19 11:53:44 +0000
commit0cbba9d6f4a65c04ca0e396c440de0c1c25945ec (patch)
tree115a33465849bfd516494e342e5ada6a5d47173b /server/src
parent457afbaeda4373541a634b12d195dd847948f1e2 (diff)
downloadvaadin-framework-0cbba9d6f4a65c04ca0e396c440de0c1c25945ec.tar.gz
vaadin-framework-0cbba9d6f4a65c04ca0e396c440de0c1c25945ec.zip
Initial support for toggling push on the fly (#11506)
Still missing is the ability to load vaadinPush.js if it has not yet been loaded. Change-Id: Ibe3596c38a7c4e3432b0396072866ee3072e6d30
Diffstat (limited to 'server/src')
-rw-r--r--server/src/com/vaadin/server/communication/AtmospherePushConnection.java8
-rw-r--r--server/src/com/vaadin/server/communication/PushConnection.java5
-rw-r--r--server/src/com/vaadin/server/communication/PushHandler.java46
-rw-r--r--server/src/com/vaadin/ui/UI.java39
4 files changed, 79 insertions, 19 deletions
diff --git a/server/src/com/vaadin/server/communication/AtmospherePushConnection.java b/server/src/com/vaadin/server/communication/AtmospherePushConnection.java
index 9b98153a23..a5025e2356 100644
--- a/server/src/com/vaadin/server/communication/AtmospherePushConnection.java
+++ b/server/src/com/vaadin/server/communication/AtmospherePushConnection.java
@@ -117,4 +117,12 @@ public class AtmospherePushConnection implements Serializable, PushConnection {
protected AtmosphereResource getResource() {
return resource;
}
+
+ @Override
+ public void disconnect() {
+ resource.resume();
+ assert !resource.getBroadcaster().getAtmosphereResources()
+ .contains(resource);
+ resource = null;
+ }
}
diff --git a/server/src/com/vaadin/server/communication/PushConnection.java b/server/src/com/vaadin/server/communication/PushConnection.java
index 590219b1b5..eecf4d93a4 100644
--- a/server/src/com/vaadin/server/communication/PushConnection.java
+++ b/server/src/com/vaadin/server/communication/PushConnection.java
@@ -35,4 +35,9 @@ public interface PushConnection {
*/
public void push();
+ /**
+ * Disconnects the connection.
+ */
+ public void disconnect();
+
} \ No newline at end of file
diff --git a/server/src/com/vaadin/server/communication/PushHandler.java b/server/src/com/vaadin/server/communication/PushHandler.java
index a9e6c17751..bdc8c723a5 100644
--- a/server/src/com/vaadin/server/communication/PushHandler.java
+++ b/server/src/com/vaadin/server/communication/PushHandler.java
@@ -38,6 +38,7 @@ import com.vaadin.server.VaadinServletRequest;
import com.vaadin.server.VaadinServletService;
import com.vaadin.server.VaadinSession;
import com.vaadin.server.WebBrowser;
+import com.vaadin.shared.communication.PushMode;
import com.vaadin.ui.UI;
/**
@@ -138,6 +139,46 @@ public class PushHandler implements AtmosphereHandler {
}
};
+ /**
+ * Callback used when a connection is closed by the client.
+ */
+ PushEventCallback disconnectCallback = new PushEventCallback() {
+ @Override
+ public void run(AtmosphereResource resource, UI ui) throws IOException {
+ PushMode pushMode = ui.getPushMode();
+ AtmospherePushConnection pushConnection = getConnectionForUI(ui);
+
+ String id = resource.uuid();
+
+ if (pushConnection == null) {
+ getLogger()
+ .log(Level.WARNING,
+ "Could not find push connection to close: {0} with transport {1}",
+ new Object[] { id, resource.transport() });
+ } else {
+ if (!pushMode.isEnabled()) {
+ /*
+ * The client is expected to close the connection after push
+ * mode has been set to disabled, just clean up some stuff
+ * and be done with it
+ */
+ getLogger().log(Level.FINEST,
+ "Connection closed for resource {0}", id);
+ } else {
+ /*
+ * Unexpected cancel, e.g. if the user closes the browser
+ * tab.
+ */
+ getLogger()
+ .log(Level.FINE,
+ "Connection unexpectedly closed for resource {0} with transport {1}",
+ new Object[] { id, resource.transport() });
+ }
+ ui.setPushConnection(null);
+ }
+ }
+ };
+
private static final String LONG_PADDING;
static {
@@ -234,10 +275,7 @@ public class PushHandler implements AtmosphereHandler {
String id = resource.uuid();
if (event.isCancelled()) {
- // The client closed the connection.
- // TODO Do some cleanup
- getLogger().log(Level.FINER, "Connection closed for resource {0}",
- id);
+ callWithUi(resource, disconnectCallback);
} else if (event.isResuming()) {
// A connection that was suspended earlier was resumed (committed to
// the client.) Should only happen if the transport is JSONP or
diff --git a/server/src/com/vaadin/ui/UI.java b/server/src/com/vaadin/ui/UI.java
index 4eff7645e2..e1646a5ac5 100644
--- a/server/src/com/vaadin/ui/UI.java
+++ b/server/src/com/vaadin/ui/UI.java
@@ -130,8 +130,6 @@ public abstract class UI extends AbstractSingleComponentContainer implements
*/
private int scrollLeft = 0;
- private PushMode pushMode;
-
private UIServerRpc rpc = new UIServerRpc() {
@Override
public void click(MouseEventDetails mouseDetails) {
@@ -1189,11 +1187,19 @@ public abstract class UI extends AbstractSingleComponentContainer implements
* Sets the internal push connection object used by this UI. This method
* should only be called by the framework.
*/
- public void setPushConnection(PushConnection connection) {
- assert pushConnection == null;
- assert connection != null;
- pushConnection = connection;
- if (hasPendingPush) {
+ public void setPushConnection(PushConnection pushConnection) {
+ assert (pushConnection != null) == (getPushMode().isEnabled());
+
+ if (pushConnection == this.pushConnection) {
+ return;
+ }
+
+ if (this.pushConnection != null) {
+ this.pushConnection.disconnect();
+ }
+
+ this.pushConnection = pushConnection;
+ if (pushConnection != null && hasPendingPush) {
hasPendingPush = false;
pushConnection.push();
}
@@ -1232,12 +1238,12 @@ public abstract class UI extends AbstractSingleComponentContainer implements
* @return The push mode.
*/
public PushMode getPushMode() {
- return pushMode;
+ return getState(false).pushMode;
}
/**
* Sets the mode of bidirectional ("push") communication that should be used
- * in this UI. Set once on UI creation and cannot be changed afterwards.
+ * in this UI.
*
* @param pushMode
* The push mode to use.
@@ -1245,16 +1251,13 @@ public abstract class UI extends AbstractSingleComponentContainer implements
* @throws IllegalArgumentException
* if the argument is null.
* @throws IllegalStateException
- * if the mode is already set or if push support is not
- * available.
+ * if push support is not available.
*/
public void setPushMode(PushMode pushMode) {
if (pushMode == null) {
throw new IllegalArgumentException("Push mode cannot be null");
}
- if (this.pushMode != null) {
- throw new IllegalStateException("Push mode already set");
- }
+
if (pushMode.isEnabled()) {
VaadinSession session = getSession();
if (session != null && !session.getService().ensurePushAvailable()) {
@@ -1262,7 +1265,13 @@ public abstract class UI extends AbstractSingleComponentContainer implements
"Push is not available. See previous log messages for more information.");
}
}
- this.pushMode = pushMode;
+
+ /*
+ * Client-side will open a new connection or disconnect the old
+ * connection, so there's nothing more to do on the server at this
+ * point.
+ */
+ getState().pushMode = pushMode;
}
}