spring websockets: sending a message to an offline

2019-02-26 01:03发布

I have a webapp with spring and websockets using a message broker (activemq).

here is my config class:

@Configuration
@EnableWebSocketMessageBroker
@EnableScheduling
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
    config.enableStompBrokerRelay("/topic","/queue/");
    config.setApplicationDestinationPrefixes("/app");
 }

@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
    registry.addEndpoint("/hello").withSockJS();
 }

}

I have a scheduled task that constantly pushing messages to the username "StanTheMan" :

@Scheduled(fixedDelay = 1000)
public void sendGreetings() {
   HelloMessage hello = new HelloMessage();
   hello.setContent("timeStamp:" + System.currentTimeMillis());
   String queueMapping = "/queue/greetings";    
   template.convertAndSendToUser(
                     "DannyD",
                     queueMapping,
                     hello);

}

Currently, if the user is NOT connected via a websocket to the server - all the messages for him are not being en-queued for him, they simply discarded. whenever he connects - fresh messages are being en-queued for him. Is it possible for me to "convertAndSendToUser" a message to an offline user in any way? i would like to en-queue messages with an expired time for offline users to be later on pushed when they are connecting again and the expired time wasn't over.

how can i achieve that? Obviously using a real message broker (activemq) supposed to help achieving that, but how?

Thanks!

2条回答
Root(大扎)
2楼-- · 2019-02-26 01:41

This is a default behavior for message brokers. And you haven't setup the ActiveMQ broker as your default broker so Spring is setting up a in-memory broker.

To achieve what you want setup/give your details of activeMQ to your spring websocket message broker. As Spring doesn't provide these settings, you have to do all the persistence settings at the ActiveMQ side. .

To setup ActiveMQ for spring websocket message broker you also need to enable stomp and use this:

registry.enableStompBrokerRelay("/topic").setRelayHost("hostName").setRelayPort("00000");

For more information checkout: http://docs.spring.io/spring/docs/4.0.0.RELEASE/javadoc-api/org/springframework/messaging/simp/config/StompBrokerRelayRegistration.html

查看更多
欢心
3楼-- · 2019-02-26 01:51

Indeed this feature can only be used to send messages to a (presently) connected user.

We plan to provide better ways to track failed messages (see SPR-10891). In the meantime as a workaround you could inject the UserSessionRegistry into your @Scheduled component and check if the getSessionIds methods returns a non-empty Set. That would indicate the user is connected.

One alternative may be to use your own convention for a queue name that each user can subscribe to (probably based on their user name or something else that's unique enough) in order to receive persistent messages. The ActiveMQ STOMP page has a section on persistent messages and expiration times.

查看更多
登录 后发表回答