MarcGiffing / wicket-spring-boot

Spring Boot starter for Apache Wicket
151 stars 61 forks source link

Notify wicket app from spring @Service #171

Closed smiesnyrobert closed 3 years ago

smiesnyrobert commented 3 years ago

Hi, is here some simple way or example how to notify wicket WebPage from spring @Service?

Eg. I have spring @Scheduled task which run every X minutes. After the task end i want notify wicket application that task ended and refresh a component. Should i use Websocket, EventListener or what? Can u provide some good example?

Thank you for your help. I greatly appreciate it.

MarcGiffing commented 3 years ago

I think Websocket is the way to go.

Take a look at the example project. If a customer is changed or edited a websocket message is sent. It uses the auto configured WebSocketMessageBroadcaster from this project. The current downside is, that it doesn't support any session or user information and everyone is receiving the message. https://github.com/MarcGiffing/wicket-spring-boot/blob/master/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/customers/create/CustomerCreatePage.java

In the CustomerListPage you can see the component update part: https://github.com/MarcGiffing/wicket-spring-boot/blob/master/wicket-spring-boot-starter-example/src/main/java/com/giffing/wicket/spring/boot/example/web/pages/customers/CustomerListPage.java

I'm currently trying to extend the WebSocketMessageBroadcaster to support user/session specific websocket messages.

smiesnyrobert commented 3 years ago

Thank you. When i tried it from wicket page/panel with @SpringBean WebSocketMessageBroadcaster its working fine. But when i want send it from spring @Service with @Autowired WebSocketMessageBroadcaster i got error: "org.apache.wicket.WicketRuntimeException: There is no application attached to current thread scheduling-1" Is something what i am missing? Some configuration or?

wicket.external.websocket=true seems doesnt matter if true or false

I will be very grateful if you help me with this.

martin-g commented 3 years ago

What is the full stack trace ? Or at least the line where the Applciation.get() is being called.

You can use Application.get(String) instead and pass the name of WicketFilter in web.xml

smiesnyrobert commented 3 years ago

Code snippet:

`@Service public class AutomatScheduler {

@Autowired
private ActionScheduleService actionScheduleService;

@Scheduled(fixedRate = 10000)
public void triggerAction() {
     actionScheduleService.runAction(actions);
}`

` @Service public class ActionScheduleService {

@Autowired
private WebSocketMessageBroadcaster webSocketMessageBroadcaster;

public void runAction() {
    webSocketMessageBroadcaster.send(new EventMessage());
}

}`

martin-g commented 3 years ago

You can roll out your own version of https://github.com/MarcGiffing/wicket-spring-boot/blob/master/wicket-spring-boot-starter/src/main/java/com/giffing/wicket/spring/boot/starter/web/servlet/websocket/WebSocketMessageSenderDefault.java that uses Application.get(String) and use it instead of the default one.

smiesnyrobert commented 3 years ago

Thank you very much!!! Great job!

this works for me:

`public class WebSocketMessageSenderDefault extends com.giffing.wicket.spring.boot.starter.web.servlet.websocket.WebSocketMessageSenderDefault {

@Override
public void send(IWebSocketPushMessage event) {
    Application application = Application.get("wicket-filter");
    WebSocketSettings webSocketSettings = WebSocketSettings.Holder.get(application);
    IWebSocketConnectionRegistry connectionRegistry = webSocketSettings.getConnectionRegistry();
    Collection<IWebSocketConnection> connections = connectionRegistry.getConnections(application);
    this.log.trace("sending event to {} connections", connections.size());
    Iterator var6 = connections.iterator();

    while(var6.hasNext()) {
        IWebSocketConnection connection = (IWebSocketConnection)var6.next();
        connection.sendMessage(event);
    }
}

}`

@Bean @Primary WebSocketMessageBroadcaster messageBroadcaster(){ return new WebSocketMessageSenderDefault(); }

martin-g commented 3 years ago

@MarcGiffing Maybe WebSocketMessageSenderDefault could be improved to inject Application instead of using Application.get() ?!