web-dev-qa-db-ja.com

Spring WebSockets @SendToマッピングのパス変数

私が思うに、非常に単純なSpring WebSocketアプリケーションがあります。ただし、サブスクリプションとメッセージマッピングにパス変数を使用しようとしています。

以下に言い換え例を掲載しました。 @SendToアノテーションは、fleetIdに基づいてサブスクライバーに戻ると予想されます。つまり、POSTから/fleet/MyFleet/driver/MyDriver/fleet/MyFleetのサブスクライバーを通知する必要がありますが、この動作は表示されません。

リテラル/fleet/{fleetId}へのサブスクライブが機能することは注目に値します。これは意図したものですか?構成の一部が欠落していますか?または、これは単に動作する方法ではありませんか?

私はまだWebSocketやこの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
    }));
36
bvulaj

@MessageMappingはプレースホルダーをサポートしますが、@SendTo宛先では公開/解決されません。現在、@SendTo注釈を使用して動的な宛先を定義する方法はありません(問題 SPR-1217 を参照)。しばらくは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);
}

Update: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);
}
88
Sergi Almar

パス内で変数を送信できます。たとえば、「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("/",":");
0
ivan rc