#spring-boot #sockets #websocket #spring-websocket #stomp
#весенняя загрузка #сокеты #websocket #spring-websocket #топать
Вопрос:
Я использую java springboot с maven, чтобы получить пакет стартовых сокетов spring boot. Мои клиенты используют angular с stompjs и sockjs-client. Я пытаюсь настроить простое приложение для веб-сокетов, которое позволяет использовать несколько комнат на основе roomId. Когда клиент присоединяется к комнате, он должен получать последние пять сообщений, отправленных в этой комнате.
Мое приложение Springboot имеет три класса, базовое приложение.java, который я использую для запуска приложения, класс конфигурации веб-сокета и контроллер веб-сокета:
@Controller
public class WebSocketController {
private final SimpMessagingTemplate template;
@Autowired
WebSocketController(SimpMessagingTemplate template){
this.template = template;
}
@MessageMapping("/meeting/{roomId}")
private void sendMessageTpPrivateRoom(
String message,
@DestinationVariable String roomId
) throws IOException {
System.out.println("message sent to: " roomId);
this.template.convertAndSend("/meeting/" roomId, message);
addToHistory(roomId, message);
}
@SubscribeMapping("/meeting/{roomId}")
public String chatInit(@DestinationVariable String roomId) {
System.out.println("Someone joined room: " roomId);
return getLastFiveMessages(roomId);
}
}
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfiguration
extends AbstractWebSocketMessageBrokerConfigurer {
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/socket")
.setAllowedOrigins("*")
.withSockJS();
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.setApplicationDestinationPrefixes("/app")
.enableSimpleBroker("/meeting");
}
}
мои клиенты подписываются на сокет следующим образом:
stompClient.subscribe(`app/meeting/${roomId}`, (message) => {
if (message.body) {
console.log(message.body);
messages = '<br>' message.body;
}
});
и отправка сообщений, подобных этому:
this.stompClient.send(`/app/meeting/${this.roomId}` , {}, message);
Отправка и обработка сообщений работают отлично, когда я настраиваю три клиента, два в первой комнате и один во второй комнате, сообщения из второй комнаты не отображаются в первой комнате, а сообщения из первой комнаты видны обоим клиентам.
Однако событие on subscribe не запускается независимо от того, к какой комнате я присоединяюсь. Очень важно, чтобы, когда клиент присоединяется к первой комнате, он получал какую-то историю этой комнаты. Любой совет относительно того, почему мой метод сопоставления подписок не запускается, когда клиент подписывается на номер?
Ответ №1:
/meeting
Часть будет неявно добавлена к URL, который вы предоставляете при подписке. Итак, ваше отображение будет выглядеть так:
@SubscribeMapping("/${roomId}")
public String chatInit(@DestinationVariable String roomId) {
System.out.println("Someone joined room: " roomId);
return getLastFiveMessages(roomId);
}
Комментарии:
1. итак, оказывается, что на самом деле мне просто нужно было добавить путь к подписке с помощью «app», чтобы полный путь был «app / meeting / roomId». Теперь, когда я присоединяюсь к комнате, я получаю свое сообщение! Но теперь возникает проблема, когда я подписываюсь на app / meeting / roomId, но когда я отправляю сообщения, поскольку я больше не подписан на regular / meeting / roomId, кажется, что я больше не получаю отправляемые сообщения. Единственный ответ, который я получаю, — это от subscribeMapping, и я предполагаю, что это связано с тем, что он больше не проходит через брокера. Есть идеи, как заставить брокера отправлять в app / meeting / roomId? Обновлено выше, чтобы отразить
2. Похоже, ожидается, что каждый клиент должен будет подписаться на app / meeting / roomId И / meeting / roomId, чтобы получить ответ на подписку, а также все будущие сообщения?