特定のセッションにメッセージを送信することはできますか?Spring WebSocket @SendToSession:特定のセッションにメッセージを送信
クライアントとSpringサーブレットの間に認証されていないwebsocketがあります。非同期ジョブが終了すると、特定の接続に非送信請求メッセージを送信する必要があります。
@Controller
public class WebsocketTest {
@Autowired
public SimpMessageSendingOperations messagingTemplate;
ExecutorService executor = Executors.newSingleThreadExecutor();
@MessageMapping("/start")
public void start(SimpMessageHeaderAccessor accessor) throws Exception {
String applicantId=accessor.getSessionId();
executor.submit(() -> {
//... slow job
jobEnd(applicantId);
});
}
public void jobEnd(String sessionId){
messagingTemplate.convertAndSend("/queue/jobend"); //how to send only to that session?
}
}
このコードでわかるように、クライアントは非同期ジョブを開始でき、終了すると終了メッセージが必要です。明らかに、私は応募者だけにメッセージを伝え、誰にでも放送する必要はありません。 @SendToSession
注釈またはmessagingTemplate.convertAndSendToSession
メソッドを持つことは素晴らしいことです。
UPDATE
私はこの試みた:
messagingTemplate.convertAndSend("/queue/jobend", true, Collections.singletonMap(SimpMessageHeaderAccessor.SESSION_ID_HEADER, sessionId));
をしかし、これはすべてのセッション、指定されたものではないだけに放送します。 convertAndSendToUserと
UPDATE 2
試験()メソッド。 このテストであり、公式の春のチュートリアルのハック:https://spring.io/guides/gs/messaging-stomp-websocket/
これは、サーバーのコードです:
@Controller
public class WebsocketTest {
@PostConstruct
public void init(){
ScheduledExecutorService statusTimerExecutor=Executors.newSingleThreadScheduledExecutor();
statusTimerExecutor.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
messagingTemplate.convertAndSendToUser("1","/queue/test", new Return("test"));
}
}, 5000,5000, TimeUnit.MILLISECONDS);
}
@Autowired
public SimpMessageSendingOperations messagingTemplate;
}
と、これはクライアントコードです:
function connect() {
var socket = new WebSocket('ws://localhost:8080/hello');
stompClient = Stomp.over(socket);
stompClient.connect({}, function(frame) {
setConnected(true);
console.log('Connected: ' + frame);
stompClient.subscribe('/user/queue/test', function(greeting){
console.log(JSON.parse(greeting.body));
});
});
}
残念ながら、クライアントが受信しません5000msごとのセッションごとの応答を期待どおりにします。私は、私は、リモート・ジョブのプログレスバーを作成したいSimpMessageHeaderAccessor.getSessionId()
背景SCENARIO
でデバッグモードでそれを見るために「1」が接続されている第二のクライアントのために、有効なセッションIDであることを確信していますクライアントはサーバーに非同期ジョブを要求し、サーバーから送信されたwebsocketメッセージによって進行状況をチェックします。これはファイルのアップロードではなくリモートでの計算であるため、サーバーだけが各ジョブの進行状況を把握しています。 セッションごとにジョブが開始されるため、特定のセッションにメッセージを送信する必要があります。 クライアントはリモート計算を要求します サーバはこのジョブを開始し、すべてのジョブステップに対して、ジョブ進行状況を持つ申請者クライアントに応答します。 クライアントはジョブに関するメッセージを取得し、進行状況/ステータスバーを作成します。 これは私がセッションごとのメッセージを必要とする理由です。 私はユーザごとのメッセージを使用することもできますが、Spring は、ユーザごとにの未承諾メッセージを提供しません。(Cannot send user message with Spring Websocket)
WORKING SOLUTION
__ __ ___ ___ _ __ ___ _ _ ___ ___ ___ _ _ _ _____ ___ ___ _ _
\ \ /// _ \ | _ \| |/ /|_ _|| \| |/__| /__|/_ \ | | | | | ||_ _||_ _|/ _ \ | \| |
\ \/\/ /| (_) || /| ' < | | | .` || (_ | \__ \| (_) || |__| |_| | | | | || (_) || .` |
\_/\_/ \___/ |_|_\|_|\_\|___||_|\_| \___| |___/ \___/ |____|\___/ |_| |___|\___/ |_|\_|
私は最後のparamでconvertAndSendToUser方法を完了しなければならなかったアップデート2溶液(MessageHeaders)最低料金:
createHeaders()
はこの方法で
messagingTemplate.convertAndSendToUser("1","/queue/test", new Return("test"), createHeaders("1"));
:
private MessageHeaders createHeaders(String sessionId) {
SimpMessageHeaderAccessor headerAccessor = SimpMessageHeaderAccessor.create(SimpMessageType.MESSAGE);
headerAccessor.setSessionId(sessionId);
headerAccessor.setLeaveMutable(true);
return headerAccessor.getMessageHeaders();
}
私はこれを見つけました:https://jira.spring.io/browse/SPR-12143 – Tobia
私はあなたに例を書いています..メッセージを送信したい特定のセッションは誰にどのように伝えられますか? – Aviad
これはリモートジョブ管理で、コントローラがリモートジョブ要求を受信すると、将来のジョブステータス応答をルーティングするために申請者のセッションを保存する必要があります – Tobia