我有一个webapp与spring和websockets使用消息代理(activemq)。
下面是我的配置类:@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连接到服务器-他的所有消息都是而不是正在为他排队,他们只是丢弃。无论何时他连接-新的消息正在为他排队。我是否有可能以任何方式将"convertAndSendToUser"消息发送给离线用户?我想为离线用户设置一个过期时间的消息队列,以便在他们再次连接并且过期时间未结束时稍后推送。
我怎样才能做到这一点?显然,使用真实的消息代理(activemq)应该有助于实现这一点,但是如何实现呢?
谢谢!
事实上,此功能只能用于向(当前)连接的用户发送消息。
我们计划提供更好的方法来跟踪失败消息(参见SPR-10891)。同时,作为一种解决方法,您可以将UserSessionRegistry
注入到@Scheduled组件中,并检查getSessionIds方法是否返回非空Set。这将表明用户已连接。
一种替代方法可能是使用您自己的约定来指定每个用户可以订阅的队列名(可能基于他们的用户名或其他足够唯一的名称),以便接收持久消息。ActiveMQ STOMP页面有一个关于持久消息和过期时间的章节。
这是消息代理的默认行为。您还没有将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