私は websocket 機能を備えた単純な春のアプリケーションを持っており、これまでのところすべてが機能しています。@SendToUser アノテーションを使用して、サーバーから特定のクライアントにメッセージを送信したいと考えています。これにより、「メッセージを無視しています。プリンシパル情報がありません」というエラーが表示されます。サーバーにログインしていないため、すべてのユーザーは「匿名」であり、プリンシパルを持っていないことを理解しています(現在、春のセキュリティを使用していません)。ただし、すべてのユーザーにはセッション ID があります。セッションIDを使用してユーザーを区別することはできませんか? ユーザーがセッション ID に対応するプリンシパルを取得できるようにするにはどうすればよいですか?
5 に答える
サブスクライブ時にキューの前に「/user/」を使用@SendToUser
して追加します (サブスクライバー側のみ)。残りは魔法のように働きます:-)
それ以外の
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){ ....
@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());
}
....
Biju の回答に基づいて構築し、Stomp によって生成されたセッション ID (同様の質問に対する彼の回答で mariusz2108 に感謝します) を使用すると、次のように機能しました ( Spring の正規の例に基づく) 。
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 用) からアクセスできないため、これはより困難な見通しです。