How to use WebSockets
Add real-time WebSocket communication to your Wicket application
- Classpath dependency
Add the following dependency to your application to get access to the wicket-native-websocket API on any JSR356 compliant application server (at the moment are supported: Tomcat 8.0+, Tomcat 7.0.47+, Jetty 9.1.0+ and JBoss Wildfly 8.0.0+):
<dependency>
<groupId>org.apache.wicket</groupId>
<artifactId>wicket-native-websocket-javax</artifactId>
<version>...</version>
</dependency>
- for Spring Boot applications also add —- <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> —-
[!NOTE] The examples above show snippets for Maven’s pom.xml but the application can use any other dependency management tool like Gradle
- web.xml
In WEB-INF/web.xml replace the usage of WicketFilter with the following:
<filter-class>org.apache.wicket.protocol.ws.javax.JavaxWebSocketFilter</filter-class>
For Spring Boot application: —- @Bean public FilterRegistrationBean wicketFilter() { final FilterRegistrationBean wicketFilter = new FilterRegistrationBean(); wicketFilter.setDispatcherTypes(DispatcherType.REQUEST, DispatcherType.ERROR, DispatcherType.FORWARD, DispatcherType.ASYNC); wicketFilter.setAsyncSupported(true); wicketFilter.setFilter(new JavaxWebSocketFilter()); wicketFilter.addInitParameter(WicketFilter.APP_FACT_PARAM, SpringWebApplicationFactory.class.getName()); wicketFilter.addInitParameter(WicketFilter.FILTER_MAPPING_PARAM, “/”); wicketFilter.addUrlPatterns(“/”); return wicketFilter; }
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
@Bean
public WicketServerEndpointConfig wicketServerEndpointConfig() {
return new WicketServerEndpointConfig();
}
* *WebSocketBehavior*
_org.apache.wicket.protocol.ws.api.WebSocketBehavior_ is similar to Wicket Ajax behaviors that you may have used.
Add WebSocketBehavior to the page (or to any component in the page) that will use web socket communication:
[source,java]
public class MyPage extends WebPage {
public MyPage()
{
add(new WebSocketBehavior() {
@Override
protected void onMessage(WebSocketRequestHandler handler, TextMessage message)
{
String msg = message.getText();
// do something with msg
}
});
}
} —-
Use message.getText() to read the message sent by the client and use handler.push(String) to push a text message to the connected client. Additionally you can use handler.add(Component…) to add Wicket components for re-render, handler.prependJavaScript(CharSequence) and handler.appendJavaScript(CharSequence) as you do with AjaxRequestTarget.
- WebSocketResource
Wicket allows one thread at a time to use a page instance to simplify the usage of the pages in multithreaded environment. When a WebSocket message is sent to a page Wicket needs to acquire the lock to that page to be able to pass the IWebSocketMessage to the WebSocketBehavior. This may be problematic when the application needs to send many messages from the client to the server. For this reason Wicket provides WebSocketResource - an IResource implementation that provides the same APIs as WebSocketBehavior. The benefit is that there is no need of synchronization as with the pages and the drawback is that WebSocketRequestHandler.add(Component…) method cannot be used because there is no access to the components in an IResource.
To register such WebSocket resource add such line to YourApplication1.init() method:
getSharedResources().add("someName", new MyWebSocketResource());
and
page.add(new BaseWebSocketBehavior("someName"));
to any page. This will prepare the JavaScript connection for you.
- WebSocket connection registry
To push data to one or more clients the application can use the IWebSocketConnectionRegistry to find all registered connections and send data to all/any of them:
Application application = Application.get(applicationName);
WebSocketSettings webSocketSettings = WebSocketSettings.Holder.get(application);
IWebSocketConnectionRegistry webSocketConnectionRegistry = webSocketSettings.getConnectionRegistry();
IWebSocketConnection connection = webSocketConnectionRegistry.getConnection(application, sessionId, key);