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屋!