我正在使用Spring WebSockets,Messaging和RabbitMQ开发基于事件的实时应用程序。在此应用程序中,消息需要按照它们插入RabbitMQ的确切顺序传递给客户端。
" EDITED"
我们的目标是从浏览器接收消息,按顺序在服务器上处理它(针对路由参数确定的唯一对象),丰富消息并通过外部STOMP MQ(RabbitMQ)将其广播到所有订阅浏览器。
我们的MessageMapping方法如下:
@MessageMapping(/命令。{路由}。{数据}) public CommandMessage receiveCommand(CommandMessage message,Principal principal){
try {
// Get object to synch on using route
Object o = ...
syncrhonized(o) {
// Perform command on object
// Set message server sequence
message.setServerSequence(o.getAutoIncrementSequence());
// Log server sequence
log.debug("Message server sequence:" + message.getServerSequence());
// Send to external MQ for broadcasting to all subscribers
return message;
}
} catch (Exception e) {
...
}
return null;
}
如果我们使用corePoolSize和maxPoolSize配置ClientInboundChannel和ClientOutboundChannels,则所有消息都是有序的。
如果我们在ClientInboundChannel上增加corePoolSize和maxPoolSize,则消息以错误的顺序到达MQ;如果我们对ClientOutboundChannel进行相同的增加,则消息会以错误的顺序进入浏览器。
使用单个浏览器客户端进行测试。
我们开启了StompBrokerRelayMessageHandler的跟踪并收到了以下日志条目:
2014-05-06 14:26:39 TRACE [clientInboundChannel-6] osmssStompBrokerRelayMessageHandler [StompBrokerRelayMessageHandler.java:412]处理消息= [Payload byte [303]] [Headers = {stompCommand = SEND,nativeHeaders = {content -type = [application / json; charset = UTF-8],destination = [/ topic / commands.BKN01.20140318]},simpMessageType = MESSAGE,simpDestination = / topic / commands.BKN01.20140318,intentType = application / json; charset = UTF-8,simpSessionId = ehjcoxb3,id = a31d0e3d-12cc-f562-1ec2-e2d7ba0899eb,timestamp = 1399400799940}] 2014-05-06 14:26:39 DEBUG [clientInboundChannel-6] o.s.m.s.s.StompBrokerRelayMessageHandler [StompBrokerRelayMessageHandler.java:658]向经纪人转发邮件 2014-05-06 14:26:39 TRACE [clientInboundChannel-3] o.s.m.s.s.StompBrokerRelayMessageHandler [StompBrokerRelayMessageHandler.java:406]忽略到目的地的消息= / app / commands.BKN01.20140318 2014-05-06 14:26:39 TRACE [clientInboundChannel-7] o.s.m.s.s.StompBrokerRelayMessageHandler [StompBrokerRelayMessageHandler.java:406]忽略到目的地的消息= / app / commands.BKN01.20140318 2014-05-06 14:26:39 TRACE [clientInboundChannel-1] osmssStompBrokerRelayMessageHandler [StompBrokerRelayMessageHandler.java:412]处理消息= [Payload byte [314]] [Headers = {stompCommand = SEND,nativeHeaders = {content-type = [application / json; charset = UTF-8],destination = [/ topic / commands.BKN01.20140318]},simpMessageType = MESSAGE,simpDestination = / topic / commands.BKN01.20140318,intentType = application / json; charset = UTF -8,simpSessionId = ehjcoxb3,id = 3cc7b4ae-8ea4-ef8a-6c4d-c3bc1ed23bcd,timestamp = 1399400799947}] 2014-05-06 14:26:39 DEBUG [clientInboundChannel-1] o.s.m.s.s.StompBrokerRelayMessageHandler [StompBrokerRelayMessageHandler.java:658]转发给经纪人的消息
我们还在org.springframework.web.socket.messaging包中为StompSubProtocolHandler启用了跟踪,并收到了以下消息:
2014-05-07 10:58:58 TRACE [http-nio-8080-exec-5] o.s.w.s.m.StompSubProtocolHandler [StompSubProtocolHandler.java:180]收到来自客户会话的消息= u8wrnsr6
这些信息都没有提供一种简单的方法来映射我们的message.serverSequence属性(在发送到MQ之前设置),其中包含日志详细信息的各种ID。
有没有办法增加入站/出站通道线程,所以订单完好无损?例如,频道是否可以绑定到"路由"或者是否可以将线程挂在"路线"?
请帮忙。
谢谢,
丹
答案 0 :(得分:2)
[EDITED]
谢谢,我现在看到了。实际上,目前无法确保来自外部代理的消息以完全相同的顺序传递给客户端,并且来自客户端的消息将以完全相同的顺序发送到外部代理。
我们可以为会话中的每个消息分配一个索引,然后在必要时检查并缓冲以强制执行订单,但这将是一个新功能。随意在JIRA中创建请求。
现在你可以考虑创建一个ChannelInterceptor,它检查每条消息以查看它所属的会话,然后在发送之前设置一些增量索引标头(在clientInboundChannel或clientOutboundChannel上)。然后扩展StompSubProtocolHandler和StompBrokerRelayMessageHandler来检查索引标题并尝试强制执行消息的顺序。