Hi, Here are the logs:
[qtp1722023916-27] INFO com.mycompany.StartWebSocketPage - onClose [Wicket-AsyncPageStore-PageSavingThread] INFO com.mycompany.WicketApplication - ===serialize class com.mycompany.StartWebSocketPage 0 [qtp1722023916-16] INFO com.mycompany.WicketApplication - ---deserialize class com.mycompany.BackgroundWorkPage 1 [qtp1722023916-16] INFO com.mycompany.BackgroundWorkPage - onEvent other org.apache.wicket.protocol.ws.api.event.WebSocketConnectedPayload@232150f0 [qtp1722023916-16] INFO com.mycompany.BackgroundWorkPage - onConnect [qtp1722023916-16] INFO com.mycompany.BackgroundWorkPage - Broadcasting com.mycompany.pushmessages.WebSocketConnected@d0ec7a9 [qtp1722023916-16] INFO com.mycompany.WicketApplication - ---deserialize class com.mycompany.BackgroundWorkPage 1 [qtp1722023916-16] INFO com.mycompany.BackgroundWorkPage - onEvent websocketpushpayload [qtp1722023916-16] INFO com.mycompany.BackgroundWorkPage - onWebSocketMessage: class com.mycompany.BackgroundWorkPage, com.mycompany.pushmessages.WebSocketConnected@d0ec7a9 [qtp1722023916-16] INFO com.mycompany.BackgroundWorkPage - received WebSocketConnected The problem is in WebSocketPage#onInitialize(): add(new WebSocketBehavior() { @Override protected void onConnect(ConnectedMessage message) { super.onConnect(message); log.info("onConnect"); connectedMessage = message; broadcast(new WebSocketConnected()); } broadcast() uses new WebSocketPushBroadcaster(webSocketSettings.getConnectionRegistry()) to broadcast the event. But since the caller is #onInitialize() the current page instance is not yet saved into the page store and the registry loads the previous version of BackgroundWorkPage id=1 (the one stored by AjaxLink#onClick() call to setResponsePage()). So the looked up page instance by WebSocket's connection registry does not see the new state (connectedMessage) Below is a diff with the changes I've made locally to debug it: diff --git pom.xml pom.xml index b49937f..202d6f2 100644 --- pom.xml +++ pom.xml @@ -41,7 +41,7 @@ </license> </licenses> <properties> - <wicket.version>8.5.0</wicket.version> + <wicket.version>8.6.0-SNAPSHOT</wicket.version> <jetty9.version>9.4.18.v20190429</jetty9.version> <slf4j.version>1.7.26</slf4j.version> <junit.version>4.12</junit.version> @@ -63,13 +63,6 @@ <version>${wicket.version}</version> </dependency> - <dependency> - <groupId>org.apache.wicket</groupId> - <artifactId>wicket-native-websocket-core</artifactId> - <version>${wicket.version}</version> - </dependency> - - <!-- OPTIONAL DEPENDENCY <dependency> <groupId>org.apache.wicket</groupId> @@ -114,14 +107,12 @@ <scope>test</scope> </dependency> - <!-- uncomment if WebSocket support is needed <dependency> <groupId>org.eclipse.jetty.websocket</groupId> <artifactId>javax-websocket-server-impl</artifactId> <version>${jetty9.version}</version> <scope>test</scope> </dependency> - --> </dependencies> <build> <resources> diff --git src/main/java/com/mycompany/BackgroundWorkPage.java src/main/java/com/mycompany/BackgroundWorkPage.java index 76d84be..4bd7b84 100644 --- src/main/java/com/mycompany/BackgroundWorkPage.java +++ src/main/java/com/mycompany/BackgroundWorkPage.java @@ -23,7 +23,6 @@ public class BackgroundWorkPage extends WebSocketPage { super(parameters); } - @Override protected void onInitialize() { super.onInitialize(); @@ -61,7 +60,7 @@ public class BackgroundWorkPage extends WebSocketPage { }); future.exceptionally(ex->{ - log.error("big caclulation failed", ex); + log.error("big calculation failed", ex); return null; }); diff --git src/main/java/com/mycompany/StartWebSocketPage.java src/main/java/com/mycompany/StartWebSocketPage.java index 56d1a99..5d1d9f6 100644 --- src/main/java/com/mycompany/StartWebSocketPage.java +++ src/main/java/com/mycompany/StartWebSocketPage.java @@ -1,12 +1,10 @@ package com.mycompany; import com.mycompany.pushmessages.WebSocketConnected; -import org.apache.wicket.Component; -import org.apache.wicket.Page; + import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.markup.html.AjaxLink; import org.apache.wicket.markup.html.link.BookmarkablePageLink; -import org.apache.wicket.model.Model; import org.apache.wicket.protocol.ws.api.WebSocketRequestHandler; import org.apache.wicket.protocol.ws.api.message.IWebSocketPushMessage; import org.apache.wicket.request.mapper.parameter.PageParameters; @@ -39,7 +37,7 @@ public class StartWebSocketPage extends WebSocketPage { setEnabled(isWebSocketConnected()); } }; - btn.setOutputMarkupId(true); + btn.setOutputMarkupPlaceholderTag(true); add(btn); @@ -50,7 +48,7 @@ public class StartWebSocketPage extends WebSocketPage { setEnabled(isWebSocketConnected()); } }; - worksBtn.setOutputMarkupId(true); + worksBtn.setOutputMarkupPlaceholderTag(true); add(worksBtn); } diff --git src/main/java/com/mycompany/WebSocketPage.java src/main/java/com/mycompany/WebSocketPage.java index bdcb47b..f6118fe 100644 --- src/main/java/com/mycompany/WebSocketPage.java +++ src/main/java/com/mycompany/WebSocketPage.java @@ -16,7 +16,7 @@ import org.slf4j.LoggerFactory; public class WebSocketPage extends WebPage { - static Logger log = LoggerFactory.getLogger(WebSocketPage.class); + Logger log = LoggerFactory.getLogger(getClass()); private ConnectedMessage connectedMessage = null; @@ -70,7 +70,7 @@ public class WebSocketPage extends WebPage { } protected void onWebSocketMessage(WebSocketRequestHandler handler, IWebSocketPushMessage message) { - + log.info("onWebSocketMessage: {}, {}", getClass(), message); } diff --git src/main/java/com/mycompany/WicketApplication.java src/main/java/com/mycompany/WicketApplication.java index 85346e5..dbb0c47 100644 --- src/main/java/com/mycompany/WicketApplication.java +++ src/main/java/com/mycompany/WicketApplication.java @@ -1,6 +1,7 @@ package com.mycompany; import org.apache.wicket.Application; +import org.apache.wicket.Page; import org.apache.wicket.markup.html.WebPage; import org.apache.wicket.protocol.http.WebApplication; import org.apache.wicket.protocol.ws.WebSocketSettings; @@ -33,10 +34,6 @@ public class WicketApplication extends WebApplication broadcaster.broadcast(connectedMsg, message); } - - - - /** * @see org.apache.wicket.Application#getHomePage() */ @@ -65,13 +62,19 @@ public class WicketApplication extends WebApplication getFrameworkSettings().setSerializer(new JavaSerializer(getApplicationKey()){ public byte[] serialize(Object obj) { - log.info("serialize " + obj.getClass() + " " + obj.hashCode()); + if (obj instanceof Page) { + Page p = (Page) obj; + log.info("===serialize " + p.getClass() + " " + p.getId()); + } return super.serialize(obj); } public Object deserialize(byte[] data) { Object res = super.deserialize(data); - log.info("deserialize " + res.getClass() + " " + res.hashCode()); + if (res instanceof Page) { + Page p = (Page) res; + log.info("---deserialize " + p.getClass() + " " + p.getId()); + } return res; } }); diff --git src/test/java/com/mycompany/Start.java src/test/java/com/mycompany/Start.java index 9acdb08..f06825d 100644 --- src/test/java/com/mycompany/Start.java +++ src/test/java/com/mycompany/Start.java @@ -3,7 +3,11 @@ package com.mycompany; import java.lang.management.ManagementFactory; import javax.management.MBeanServer; +import javax.servlet.ServletException; +import javax.websocket.DeploymentException; +import javax.websocket.server.ServerContainer; +import org.apache.wicket.protocol.ws.javax.WicketServerEndpointConfig; import org.eclipse.jetty.jmx.MBeanContainer; import org.eclipse.jetty.server.HttpConfiguration; import org.eclipse.jetty.server.HttpConnectionFactory; @@ -14,6 +18,7 @@ import org.eclipse.jetty.server.SslConnectionFactory; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.webapp.WebAppContext; +import org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer; /** * Separate startup class for people that want to run the examples directly. Use parameter @@ -26,8 +31,7 @@ public class Start * * @param args */ - public static void main(String[] args) - { + public static void main(String[] args) throws DeploymentException, ServletException { System.setProperty("wicket.configuration", "development"); Server server = new Server(); @@ -80,8 +84,8 @@ public class Start // uncomment the next two lines if you want to start Jetty with WebSocket (JSR-356) support // you need org.apache.wicket:wicket-native-websocket-javax in the classpath! - // ServerContainer serverContainer = WebSocketServerContainerInitializer.configureContext(bb); - // serverContainer.addEndpoint(new WicketServerEndpointConfig()); + ServerContainer serverContainer = WebSocketServerContainerInitializer.configureContext(bb); + serverContainer.addEndpoint(new WicketServerEndpointConfig()); // uncomment next line if you want to test with JSESSIONID encoded in the urls // ((AbstractSessionManager) On Tue, Jul 2, 2019 at 1:14 PM Peter Henderson <peter.hender...@starjar.com> wrote: > Hi all, > > QuickStart: https://github.com/bollinger/WicketWebsocketsTest > > > > I have a page StartPage[1] which uses web sockets. On this page there is an > AjaxLink which redirects to a BackgroundPage[2]. > > > The BackgroundPage also uses web sockets. It waits for a web socket > connection, then kicks off some background work. When the work completes it > tries to display the results. > > > > When navigating directly to the Background page or via a bookmarkable link, > all works as expected. > > > When arriving at Background page via the AjaxLink funky stuff happens. The > background work completes but it cannot send a message to the page to > refresh because the stored connectedMessage is null. > > Looking at the serialization it seems like there are 2 background pages. > > > > I’m probably doing something incorrectly, but what? > > > Many thanks. > > Peter. > > > > [1] > > > https://github.com/bollinger/WicketWebsocketsTest/blob/master/src/main/java/com/mycompany/StartWebSocketPage.java > > > > [2] > > > https://github.com/bollinger/WicketWebsocketsTest/blob/master/src/main/java/com/mycompany/BackgroundWorkPage.java > > > -- > Peter Henderson >