Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trigger repainting a wicket component via push message

I understand the concept of repainting wicket components using add(Component) method of AjaxRequestTarget - but I can only use this method when the client triggers some ajax event.

But I have to repaint a component without any user interaction involved, so I can't use that. Next step was to discover WebSocketBehavior and it's associated method onMessage() - this message again gets a parameter of type WebSocketRequestHandler (which extends AjaxRequestTarget) to that I could add my to-be-repainted-component. But again this method seems only to be called when the client sends a websocket-message to the server.

Lastly I discovered I can trigger asynchronous messages from server side by opening an IWebSocketConnection. Wicketinaction suggests in this blog post (http://wicketinaction.com/2012/07/wicket-6-native-websockets/) the following code lines:

IWebSocketConnectionRegistry registry = new SimpleWebSocketConnectionRegistry();
Application application = Application.get(wsApplicationName);
IWebSocketConnection wsConnection = registry.getConnection(application, wsSessionId, wsPageId);

if (wsConnection != null && wsConnection.isOpen()) {
  try {
    wsConnection.sendMessage("test");
  } catch (IOException e) {}
}

wsApplication, wsSessionId and wsPageId are obtained in the onConnect method of the WebSocketBehavior.

In general this approach works - I can send my test message to the client and it receives exactly this text. But I can't find a way how to trigger a component repaint with this method. Any suggestions on this would be appreciated - or am I completely wrong in the end?

like image 265
sina Avatar asked Oct 02 '22 09:10

sina


2 Answers

Check https://github.com/martin-g/blogs/tree/master/wicket6-websocket-broadcast. This example shows exactly what you want.

https://github.com/martin-g/blogs/blob/master/wicket6-websocket-broadcast/src/main/java/com/wicketinaction/TimestamperTask.java#L27

https://github.com/martin-g/blogs/blob/master/wicket6-websocket-broadcast/src/main/java/com/wicketinaction/FeedPage.java#L78

like image 168
martin-g Avatar answered Oct 13 '22 12:10

martin-g


Take a look at https://github.com/papegaaij/wicket-atmosphere-quickstart/ which is an example of pushing the current time repeatedly as a Wicket Component via Atmosphere (library to use WebSockets or fallbacks).

It is based on wicket-atmosphere which in turn makes Atmosphere available in Wicket. The module is considered experimental hence the location in Wicket's repository. Despite this, it seems to work pretty reliably and is definitely worth a try.

The following fragments are taken from the mentioned example but make sure to read Atmosphere's documentation and the code of wicket-atmosphere to learn its API. Basically, you create a central event dispatcher and mark method of your pages with annotations that format the events as needed and send via the provided AjaxRequestTarget.

Creating an event to a central event dispatcher from a background job: eventBus.post(new Date());

Converting the event and sending as Component:

@Subscribe
public void updateTime(AjaxRequestTarget target, Date event) {
    timeLabel.setDefaultModelObject(event.toString());
    target.add(timeLabel);
}
like image 21
Augustus Kling Avatar answered Oct 13 '22 12:10

Augustus Kling