澄清:
由于@JustinBertram的评论,我意识到这个问题没有道理。
STOMP协议本身不支持选择器,您必须使用实现该协议的代理(例如ActiveMQ)。 STOMP支持标头,代理可以使用这些标头来通过选择器过滤消息。
就我而言,我没有使用任何代理,只是使用Angular + Stomp + SocksJS进行前端,而使用Spring Boot进行后端,所以我不能使用选择器。
STOMP协议的文档对我来说并不清楚,我感到困惑。请参阅以下参考:
踩踏经纪人可能支持选择器标头,使您可以 在邮件标头上指定一个SQL 92选择器,该选择器用作 过滤基于内容的路由。
subscribe()方法采用可选的headers参数来指定 订阅目标时的其他标头:
var headers = {ack: 'client', 'selector': "location = 'Europe'"}; client.subscribe("/queue/test", message_callback, headers);
客户端指定它将处理消息确认 并且有兴趣仅接收与选择器匹配的消息 location ='欧洲'。
我正在Spring Boot中实现一个后端。为了与前端进行双向通信,我在Websocket上使用了stomp。
我关注了this Spring Boot + Angular example
它可以工作,但是我的要求之一是后端必须使用选择器发送消息,以便前端订阅一个主题并仅接收经过过滤的数据,以避免实时性能问题数据。
即{ 'selector': "location = 'Europe'" }
为此,我正在尝试使后端使用选择器发送消息,但是我无法使其工作。
我遵循this article来使用选择器实现前端,并且它可以正常工作,问题仅在于后端。
我尝试使用@SendTo
批注,但根据文章看来,它没有任何参数:
@MessageMapping("/hello")
@SendTo("/topic/greetings")
public Greeting greeting(HelloMessage message) throws Exception {
Thread.sleep(1000);
return new Greeting("Hello, " + HtmlUtils.htmlEscape(message.getName()) + "!");
}
我也尝试过使用MessagingTemplate
,但是我不知道如何在标题中设置选择器属性:
http://assets.spring.io/wp/WebSocketBlogPost.html
MessageSendingOperations<String> messagingTemplate;
messagingTemplate.convertAndSend(destination, quote);
我真的很感谢您的帮助,我已经阅读了许多文章和文档,但是没有找到关于此问题的解决方案。
答案 0 :(得分:2)
好吧,可以将JMS的选择器与Spring(引导)Websocket和STOMP客户端一起使用。我找到了本机方式。
关键是将选择器应用于org.springframework.messaging.Message
实例,并且它使用Spring的Spel 语言来应用条件(不是JMS类似SQL)。
因此,使用默认的SimpMessagingTemplate,您可以在后端发送像这样的标头变量:
this.messagingTemplate.convertAndSend(
"/topic/something", //your destination
payload, //any kind of payload (body)
Map.of("id", 1) //header with key/value
);
在前端,要输入将由org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry.filterSubscriptions
进行评估的选择器,必须将Stomp / WebSockets标头声明为:
{"selector": "headers['nativeHeaders']['id'][0] == '999'"}
是的,这太可怕了,但是有效。
由于默认的Message
是GenericMessage
,因此将在名为“ nativeHeaders” 的新密钥中处理标头。
['key'],[0] and ==
是Spring的Spel语法。
请继续,并在后端而不是在前端过滤您的消息!
答案 1 :(得分:1)
latest version of the STOMP specification不包含有关选择器及其语法的任何特定声明,因为这实际上取决于中间件在此处支持的实现。规范现在说明:
STOMP服务器可以支持其他服务器特定的头,以自定义订阅的传递语义。有关详细信息,请查阅服务器的文档。
像ActiveMQ 5.x和ActiveMQ Artemis这样的经纪人都支持selector
STOMP标头,并且选择器的语法和行为基于JMS选择器。
选择器用于在消费时选择消息,并且由消费方客户端配置。发送消息时无法设置选择器。
JMS选择器根据消息的标题或属性来选择消息,尽管某些实现超出了此范围,并允许基于消息本身的内容进行选择。因此,如果要在使用者上使用选择器location = 'Europe'
,则应在邮件以名称location
和值Europe
发送时在邮件上设置标头。>
convertAndSend
方法已重载,并提供了几种设置标头的方法:
convertAndSend
方法。MessagePostProcessor
并将其传递给convertAndSend
方法。在后处理器内部,您可以调用javax.jms.Message#setStringProperty()
方法。