diff options
author | Leif Åstrand <leif@vaadin.com> | 2013-04-18 12:35:10 +0300 |
---|---|---|
committer | Vaadin Code Review <review@vaadin.com> | 2013-04-19 11:53:44 +0000 |
commit | 0cbba9d6f4a65c04ca0e396c440de0c1c25945ec (patch) | |
tree | 115a33465849bfd516494e342e5ada6a5d47173b /server | |
parent | 457afbaeda4373541a634b12d195dd847948f1e2 (diff) | |
download | vaadin-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')
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; } } |