The UI.pushConnection field is transient no longer; instead PushConnection implementations must take care of serialization internally. When a session is serialized, the client should notice that push was disconnected and try to reconnect. A deserialized PushConnection should be in a "disconnected" state so the eventual client reconnection works correctly. Change-Id: I38cfc5a5cdbd3643311f830f8d580458dcd85c56tags/7.3.0.alpha3
@@ -17,6 +17,7 @@ | |||
package com.vaadin.server.communication; | |||
import java.io.IOException; | |||
import java.io.ObjectInputStream; | |||
import java.io.Reader; | |||
import java.io.Serializable; | |||
import java.io.StringReader; | |||
@@ -117,11 +118,11 @@ public class AtmospherePushConnection implements PushConnection { | |||
CONNECTED; | |||
} | |||
private State state = State.DISCONNECTED; | |||
private UI ui; | |||
private AtmosphereResource resource; | |||
private FragmentedMessage incomingMessage; | |||
private Future<Object> outgoingMessage; | |||
private transient State state = State.DISCONNECTED; | |||
private transient AtmosphereResource resource; | |||
private transient FragmentedMessage incomingMessage; | |||
private transient Future<Object> outgoingMessage; | |||
public AtmospherePushConnection(UI ui) { | |||
this.ui = ui; | |||
@@ -209,6 +210,7 @@ public class AtmospherePushConnection implements PushConnection { | |||
@Override | |||
public boolean isConnected() { | |||
assert state != null; | |||
assert (state == State.CONNECTED) ^ (resource == null); | |||
return state == State.CONNECTED; | |||
} | |||
@@ -297,8 +299,25 @@ public class AtmospherePushConnection implements PushConnection { | |||
state = State.DISCONNECTED; | |||
} | |||
/** | |||
* Returns the state of this connection. | |||
*/ | |||
protected State getState() { | |||
return state; | |||
} | |||
/** | |||
* Reinitializes this PushConnection after deserialization. The connection | |||
* is initially in disconnected state; the client will handle the | |||
* reconnecting. | |||
*/ | |||
private void readObject(ObjectInputStream stream) throws IOException, | |||
ClassNotFoundException { | |||
stream.defaultReadObject(); | |||
state = State.DISCONNECTED; | |||
} | |||
private static Logger getLogger() { | |||
return Logger.getLogger(AtmospherePushConnection.class.getName()); | |||
} | |||
} |
@@ -16,6 +16,8 @@ | |||
package com.vaadin.server.communication; | |||
import java.io.Serializable; | |||
import com.vaadin.ui.UI; | |||
/** | |||
@@ -30,7 +32,7 @@ import com.vaadin.ui.UI; | |||
* @author Vaadin Ltd | |||
* @since 7.1 | |||
*/ | |||
public interface PushConnection { | |||
public interface PushConnection extends Serializable { | |||
/** | |||
* Pushes pending state changes and client RPC calls to the client. Can be |
@@ -553,7 +553,7 @@ public abstract class UI extends AbstractSingleComponentContainer implements | |||
private Navigator navigator; | |||
private transient PushConnection pushConnection = null; | |||
private PushConnection pushConnection = null; | |||
private LocaleService localeService = new LocaleService(this, | |||
getState(false).localeServiceState); | |||
@@ -1626,5 +1626,4 @@ public abstract class UI extends AbstractSingleComponentContainer implements | |||
public String getEmbedId() { | |||
return embedId; | |||
} | |||
} |
@@ -0,0 +1,56 @@ | |||
/* | |||
* Copyright 2000-2014 Vaadin Ltd. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not | |||
* use this file except in compliance with the License. You may obtain a copy of | |||
* the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |||
* License for the specific language governing permissions and limitations under | |||
* the License. | |||
*/ | |||
package com.vaadin.server.communication; | |||
import java.io.ByteArrayInputStream; | |||
import java.io.ByteArrayOutputStream; | |||
import java.io.ObjectInputStream; | |||
import java.io.ObjectOutputStream; | |||
import org.atmosphere.cpr.AtmosphereResource; | |||
import org.easymock.EasyMock; | |||
import org.junit.Assert; | |||
import org.junit.Test; | |||
import com.vaadin.server.communication.AtmospherePushConnection.State; | |||
import com.vaadin.ui.UI; | |||
/** | |||
* @author Vaadin Ltd | |||
*/ | |||
public class AtmospherePushConnectionTest { | |||
@Test | |||
public void testSerialization() throws Exception { | |||
UI ui = EasyMock.createNiceMock(UI.class); | |||
AtmosphereResource resource = EasyMock | |||
.createNiceMock(AtmosphereResource.class); | |||
AtmospherePushConnection connection = new AtmospherePushConnection(ui); | |||
connection.connect(resource); | |||
Assert.assertEquals(State.CONNECTED, connection.getState()); | |||
ByteArrayOutputStream baos = new ByteArrayOutputStream(); | |||
new ObjectOutputStream(baos).writeObject(connection); | |||
connection = (AtmospherePushConnection) new ObjectInputStream( | |||
new ByteArrayInputStream(baos.toByteArray())).readObject(); | |||
Assert.assertEquals(State.DISCONNECTED, connection.getState()); | |||
} | |||
} |