4

我有一个使用消息代理(activemq)的带有spring和websockets的webapp。

这是我的配置类:

@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();
 }

}

我有一个计划任务,不断向用户名“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);

}

目前,如果用户没有通过 websocket 连接到服务器 - 他的所有消息都没有为他排队,他们只是丢弃了每当他连接时 -都会为他排队等待新消息。我是否可以以任何方式将消息“转换并发送到用户”给离线用户?我想将过期时间的消息排入队列,以便离线用户稍后在他们再次连接并且过期时间未结束时推送。

我怎样才能做到这一点?显然使用真正的消息代理(activemq)应该有助于实现这一目标,但是如何实现呢?

谢谢!

4

2 回答 2

6

实际上,此功能只能用于向(当前)连接的用户发送消息。

我们计划提供更好的方法来跟踪失败的消息(请参阅SPR-10891)。同时,作为一种解决方法,您可以将其UserSessionRegistry注入您的 @Scheduled 组件并检查 getSessionIds 方法是否返回非空集。这将表明用户已连接。

一种替代方法可能是对每个用户可以订阅的队列名称(可能基于他们的用户名或其他足够独特的东西)使用您自己的约定,以便接收持久消息。ActiveMQ STOMP 页面有一个关于持久消息和过期时间的部分。

于 2014-05-30T16:37:53.107 回答
-1

这是消息代理的默认行为。而且您还没有将 ActiveMQ 代理设置为默认代理,因此 Spring 正在设置内存代理。

为了实现您想要的设置/将您的 activeMQ 详细信息提供给您的 spring websocket 消息代理。由于 Spring 不提供这些设置,因此您必须在 ActiveMQ 端进行所有持久性设置。.

要为 spring websocket 消息代理设置 ActiveMQ,您还需要启用 stomp 并使用它:

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

欲了解更多信息结帐: http ://docs.spring.io/spring/docs/4.0.0.RELEASE/javadoc-api/org/springframework/messaging/simp/config/StompBrokerRelayRegistration.html

于 2014-05-26T08:11:10.163 回答