Spring WebSockets @SendTo映射中的路径变量 [英] Path variables in Spring WebSockets @SendTo mapping
问题描述
我有一个非常简单的Spring WebSocket应用程序.但是,我正在尝试使用路径变量进行订阅以及消息映射.
I have, what I think to be, a very simple Spring WebSocket application. However, I'm trying to use path variables for the subscription as well as the message mapping.
我在下面发布了一个释义的示例.我希望@SendTo
批注将根据订户的fleetId
返回给订户.也就是说,从POST
到/fleet/MyFleet/driver/MyDriver
应当通知订户/fleet/MyFleet
,但是我没有看到此行为.
I've posted a paraphrased example below. I would expect the @SendTo
annotation to return back to the subscribers based on their fleetId
. ie, a POST
to /fleet/MyFleet/driver/MyDriver
should notify subscribers of /fleet/MyFleet
, but I'm not seeing this behavior.
值得注意的是,订阅文字/fleet/{fleetId}
可以正常工作.这是故意的吗?我是否缺少某些配置?还是这不是它的工作原理?
It's worth noting that subscribing to literal /fleet/{fleetId}
works. Is this intended? Am I missing some piece of configuration? Or is this just not how it works?
我对WebSockets或这个Spring项目还不是很熟悉,所以在此先感谢.
I'm not very familiar with WebSockets or this Spring project yet, so thanks in advance.
Controller.java
...
@MessageMapping("/fleet/{fleetId}/driver/{driverId}")
@SendTo("/topic/fleet/{fleetId}")
public Simple simple(@DestinationVariable String fleetId, @DestinationVariable String driverId) {
return new Simple(fleetId, driverId);
}
...
WebSocketConfig.java
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
config.setApplicationDestinationPrefixes("/live");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/fleet").withSockJS();
}
}
index.html
var socket = new SockJS('/fleet');
var stompClient = Stomp.over(socket);
stompClient.connect({}, function(frame) {
// Doesn't Work
stompClient.subscribe('/topic/fleet/MyFleet', function(greeting) {
// Works
stompClient.subscribe('/topic/fleet/{fleetId}', function(greeting) {
// Do some stuff
});
});
发送示例
stompClient.send("/live/fleet/MyFleet/driver/MyDriver", {}, JSON.stringify({
// Some simple content
}));
推荐答案
即使@MessageMapping
支持占位符,它们也不会在@SendTo
目标中公开/解析.当前,无法使用@SendTo
注释定义动态目的地(请参见问题 SPR-12170 ).您可以暂时使用SimpMessagingTemplate
(无论如何这就是它内部的工作方式).这是您的操作方式:
Even though @MessageMapping
supports placeholders, they are not exposed / resolved in @SendTo
destinations. Currently, there's no way to define dynamic destinations with the @SendTo
annotation (see issue SPR-12170). You could use the SimpMessagingTemplate
for the time being (that's how it works internally anyway). Here's how you would do it:
@MessageMapping("/fleet/{fleetId}/driver/{driverId}")
public void simple(@DestinationVariable String fleetId, @DestinationVariable String driverId) {
simpMessagingTemplate.convertAndSend("/topic/fleet/" + fleetId, new Simple(fleetId, driverId));
}
在您的代码中,将目标'/topic/fleet/{fleetId} '视为文字,这就是订阅它起作用的原因,只是因为您发送的是完全相同的目的地.
In your code, the destination '/topic/fleet/{fleetId}' is treated as a literal, that's the reason why subscribing to it works, just because you are sending to the exact same destination.
如果您只想发送一些特定于用户的初始数据,则可以直接在订阅中将其返回:
If you just want to send some initial user specific data, you could return it directly in the subscription:
@SubscribeMapping("/fleet/{fleetId}/driver/{driverId}")
public Simple simple(@DestinationVariable String fleetId, @DestinationVariable String driverId) {
return new Simple(fleetId, driverId);
}
更新: 在Spring 4.2中,支持目标变量占位符,现在可以执行以下操作:
Update: In Spring 4.2, destination variable placeholders are supported it's now possible to do something like:
@MessageMapping("/fleet/{fleetId}/driver/{driverId}")
@SendTo("/topic/fleet/{fleetId}")
public Simple simple(@DestinationVariable String fleetId, @DestinationVariable String driverId) {
return new Simple(fleetId, driverId);
}
这篇关于Spring WebSockets @SendTo映射中的路径变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!