Spring Websocket @SendToUser ログインせずに?
-
02-01-2020 - |
質問
WebSocket 機能を備えたシンプルな Spring アプリケーションがあり、これまでのところすべてが機能しています。ここで、@SendToUser アノテーションを使用してサーバーから特定のクライアントにメッセージを送信したいと考えています。これにより、「メッセージを無視しています。利用可能なプリンシパル情報がありません」というエラーが表示されます。私のサーバーにはログインがまったくないため、すべてのユーザーは「匿名」であり、プリンシパルを持たないことを理解しています(今のところSpring Securityを使用していません)。ただし、すべてのユーザーはセッション ID を持っています。何らかの方法でセッションIDを使用してユーザーを区別することはできませんか?ユーザーがセッション ID に対応するプリンシパルを取得できるようにするにはどうすればよいですか?
解決
解決策は使用を避けることだと思います @SendToUser
そして生で使います SimpMessagingTemplate
開いているセッションに対して制御する宛先にメッセージを送信します。
たとえば。新しい WebSocket セッションに対する何らかの ID があると仮定すると、キュー名にその ID を使用してキューにサブスクライブできます。
stomp.subscribe("/queue/chats" + "-" + mycustomidentifier, onmessage);
これで、Spring WebSocket リスナー側で、次を使用して応答を指示できます。 SimpMessagingTemplate
:
@Controller
public class MyController {
@Autowired
private SimpMessagingTemplate simpMessagingTemplate;
@MessageMapping("/chats")
public void handleChat(@Payload ChatMessage message) {
this.simpMessagingTemplate.convertAndSend("/queue/chats-" + "mycustomidentifier", "[" + getTimestamp() + "]:" + message.getMessage());
}
....
他のヒント
使用 @SendToUser
サブスクライブ時にキューの前に「/user/」を追加します(サブスクライバー側のみ)。休息は魔法の働きをします:-)
の代わりに
Java Server: @SendTo("/topic/showResult")
そして
JS Client: stompClient.subscribe('/topic/showResult', function(calResult){ ....
使用:
Java Server: @SentToUser("/topic/showResult")
そして
JS Client: stompClient.subscribe('/user/topic/showResult', function(calResult){ ....
建物 Bijuの答えと stomp生成されたセッションID を使用する(感謝、
SpringFrameworkクライアント:
private SimpMessagingTemplate template;
@Autowired
public GreetingController(SimpMessagingTemplate template) {
this.template = template;
}
@MessageMapping("/hello")
public void greeting(HelloMessage message, @Header("simpSessionId") String sessionId) throws Exception {
template.convertAndSend("/queue/greeting-"+sessionId, new Greeting("Hello, " + message.getName()));
}
.
JavaScriptクライアント:
function connect() {
var socket = new SockJS('/gs-guide-websocket');
stompClient = Stomp.over(socket);
stompClient.connect({}, function (frame) {
var sessionId = /\/([^\/]+)\/websocket/.exec(socket._transport.url)[1];
console.log("connected, session id: " + sessionId);
stompClient.subscribe('/queue/greeting-'+sessionId, function (greeting) {
showGreeting(JSON.parse(greeting.body).content);
});
});
}
.
StompセッションIDの代わりにWebコンテナのセッションID(例:JSessionID)を使用できますが、CookieはデフォルトではありませんJavaScript (Tomcat用)から、これはより難しい見込み客です。
これを試してください。それは私のために働きました
@Autowired
private SimpMessagingTemplate messagingTemplate;
@MessageMapping("/getHello")
public void sendReply( MessageHeaders messageHeaders, @Payload String message, @Header(name = "simpSessionId") String sessionId){
messagingTemplate.convertAndSendToUser(sessionId, "/queue/hello", "Hello "+ message, messageHeaders);
}
.