是否可以向特定会话发送消息?
我有一个未经身份验证的客户端和Spring servlet之间的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));
但是,这广播到所有会话,不仅仅是指定的。
更新2
这是服务器代码:
@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收到一次会话回复。我确定“1”是第二个客户端连接的有效sessionId,因为我在SimpMessageHeaderAccessor.getSessionId()的调试模式下看到它,
背景情景
我想为远程作业创建进度条,客户端要求服务器进行异步作业,并通过从服务器发送的websocket消息来检查进度。这不是文件上传,而是远程计算,所以只有服务器知道每个作业的进度。
我需要发送一个消息到特定的会话,因为每个工作是由会话启动。
客户端要求进行远程计算
服务器启动此工作,并为每个工作步骤回复申请客户的工作进度状态。
客户端获取有关其作业的消息并构建进度/状态栏。
这就是为什么我需要一个每个会话的消息。
我也可以使用每个用户的消息,但是Spring不会为每个用户提供不请自来的消息。 (Cannot send user message with Spring Websocket)
工作解决方案
__ __ ___ ___ _ __ ___ _ _ ___ ___ ___ _ _ _ _____ ___ ___ _ _
\ \ / // _ \ | _ \| |/ /|_ _|| \| | / __| / __| / _ \ | | | | | ||_ _||_ _|/ _ \ | \| |
\ \/\/ /| (_) || /| ' < | | | .` || (_ | \__ \| (_) || |__| |_| | | | | || (_) || .` |
\_/\_/ \___/ |_|_\|_|\_\|___||_|\_| \___| |___/ \___/ |____|\___/ |_| |___|\___/ |_|\_|
从UPDATE2解决方案开始,我必须用最后一个param(MessageHeaders)完成convertAndSendToUser方法:
messagingTemplate.convertAndSendToUser("1","/queue/test", new Return("test"), createHeaders("1"));
其中createHeaders()是这种方法:
private MessageHeaders createHeaders(String sessionId) {
SimpMessageHeaderAccessor headerAccessor = SimpMessageHeaderAccessor.create(SimpMessageType.MESSAGE);
headerAccessor.setSessionId(sessionId);
headerAccessor.setLeaveMutable(true);
return headerAccessor.getMessageHeaders();
}