Не удается отправить сообщение пользователя с помощью Spring Websocket
Я прочитал документы Spring о пользовательских направлениях. Я хотел бы использовать convertAndSendToUser
способ отправить сообщение только конкретному пользователю.
Это код Java:
@Controller
public class WebsocketTest {
@Autowired
public SimpMessageSendingOperations messagingTemplate;
@PostConstruct
public void init(){
ScheduledExecutorService statusTimerExecutor=Executors.newSingleThreadScheduledExecutor();
statusTimerExecutor.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
messagingTemplate.convertAndSendToUser("myuser","/queue/test", new Return("test"));
}
}, 5000,5000, TimeUnit.MILLISECONDS);
}
}
Это код js клиента:
var socket = new WebSocket('ws://localhost:8080/hello');
stompClient = Stomp.over(socket);
stompClient.connect("myuser","mypass", function(frame) {
setConnected(true);
console.log('Connected: ' + frame);
stompClient.subscribe('/topic/greetings', function(greeting){
showGreeting(JSON.parse(greeting.body).value);
});
stompClient.subscribe('/user/queue/test', function(greeting){
showGreeting(JSON.parse(greeting.body).value);
});
});
Прежде всего, правильно ли учитывать значение этого пользователя?
stompClient.connect ("myuser",...
Почему этот тест не работает? Этот пользователь не получил ни одного сообщения. Если я переключу пункт назначения на /topic/greetings
и измените метод на convertAndSend()
это работает, но, очевидно, как широковещательная, а не только для конкретного пользователя в соответствии с просьбой
Небольшое обновление
Я попытался настроить ответ для одного пользователя с этим кодом:
@MessageMapping("/hello")
@SendToUser("/queue/test")
public Return test(){
return new Return("test");
}
Это работает, это не то, что мне нужно, потому что этот ответ только на сообщение от клиента. Кажется, я не могу использовать convertAndSendToUser()
для незапрошенных сообщений с сервера.
2 ответа
Возможно, уже поздно отвечать на вопрос, но для людей, которые могут столкнуться с подобной проблемой, вот что мне не хватало: URL-адрес веб-сокета, к которому вы подключаетесь, также должен быть защищенным URL-адресом. Если это не так, то нет сопоставления между пользователем и сеансом, и, следовательно, вы не можете отправить сообщение пользователю, используя convertAndSendToUser()
,
Так, например, вы подключаетесь к конечной точке с помощью шаблона URL /hello
тогда он должен быть защищенным.
Подписка на /user/queue/test
на стороне клиента и используя convertAndSendToUser
отправить сообщение /topic/test
тема выглядит правильно.
Теперь, как вы получаете "myUser"
значение?
Вы можете получить это значение либо request.getUserPrincipal()
во время рукопожатия или ввести Principal
при получении сообщения; Идентификатор сессии также работает здесь. Вы можете проверить этот коммит для более подробной информации по этому вопросу.