我有,我认为是一个非常简单的Spring WebSocket应用程序。但是,我尝试使用路径变量进行订阅以及消息映射。
我在下面发布了一个释义的例子。我希望@SendTo
注释会根据其fleetId
返回给订阅者。即,POST
到/fleet/MyFleet/driver/MyDriver
应通知/fleet/MyFleet
的订阅者,但我没有看到此行为。
值得注意的是订阅文字/fleet/{fleetId}
是有效的。这是有意的吗?我错过了一些配置吗?或者这不是它的工作原理?
我还不熟悉WebSockets或Spring项目,所以提前感谢。
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
}));
答案 0 :(得分:86)
即使@MessageMapping
支持占位符,也不会在@SendTo
目的地中公开/解析它们。目前,无法使用@SendTo
注释定义动态目标(请参阅问题SPR-12170)。您暂时可以使用SimpMessagingTemplate
(无论如何,它是如何在内部工作的)。以下是您的表现方式:
@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} '被视为文字,这就是订阅它的原因,只是因为你发送到完全相同的目的地。
如果您只想发送一些初始用户特定数据,可以直接在订阅中返回:
@SubscribeMapping("/fleet/{fleetId}/driver/{driverId}")
public Simple simple(@DestinationVariable String fleetId, @DestinationVariable String driverId) {
return new Simple(fleetId, driverId);
}
<强>更新强> 在Spring 4.2中,支持目标变量占位符,它现在可以执行以下操作:
@MessageMapping("/fleet/{fleetId}/driver/{driverId}")
@SendTo("/topic/fleet/{fleetId}")
public Simple simple(@DestinationVariable String fleetId, @DestinationVariable String driverId) {
return new Simple(fleetId, driverId);
}
答案 1 :(得分:0)
您可以在路径内发送变量。例如,我发送“ este / es / el / chat / java / ”并在服务器中标记为“ este:es:el:chat:java:”
客户端:
stompSession.send("/app/chat/este/es/el/chat/java/*", ...);
服务器:
@MessageMapping("/chat/**")
@SendToUser("/queue/reply")
public WebsocketData greeting(Message m,HelloMessage message,@Header("simpSessionId") String sessionId) throws Exception {
Map<String, LinkedList<String>> nativeHeaders = (Map<String, LinkedList<String>>) m.getHeaders().get("nativeHeaders");
String value= nativeHeaders.get("destination").getFirst().replaceAll("/app/chat/","").replaceAll("/",":");
答案 2 :(得分:0)
实际上,我认为这是您可能想要的:
@Autorwired
lateinit var template: SimpMessageTemplate;
@MessageMapping("/class/{id}")
@Throws(Exception::class)
fun onOffer(@DestinationVariable("id") id: String?, @Payload msg: Message) {
println("RECEIVED " + id)
template.convertAndSend("/topic/class/$id", Message("The response"))
}
希望这对某人有帮助! :)