Мой вопрос в первую очередь будет заключаться в том, почему вы пытаетесь отправить http-запрос на остальной контроллер, когда вы успешно интегрировали веб-сокеты с stomp? Если я правильно понимаю ваш вариант использования, я могу придумать три решения atm.
Решение 1 (идентификатор продукта сеанса сокета)
Вы можете отправить свой запрос напрямую с вашего клиента на сервер через открытое соединение через веб-сокет. Затем Spring может определить, какой сеанс Websocket выполнил вызов, и вы можете реализовать свою бизнес-логику. Вам нужно активировать другого брокера с именем «/queue» и указать префикс для целевого пользователя, который необходим, когда подписка не предназначена для трансляции. На стороне клиента также необходимо изменить путь подписки. Наконец, вы должны создать класс с комментарием @Controller, который содержит ваши сопоставления сообщений для получения сообщений от подключенного клиента.
Конфигурация сервера
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/websocket").withSockJS();
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableSimpleBroker("/queue", "/product"); // <- added "/queue"
registry.setApplicationDestinationPrefixes("/app");
registry.setUserDestinationPrefix("/user");
}
}
Контроллер сервера
@Controller
public class WebSocketContoller{
@Autowired
private SimpMessagingTemplate simpMessagingTemplate;
@MessageMapping("/product/register")
public void register(@Payload Long productId, @Header("simpSessionId") String sessionId) {
// register current websocket session with product id and
// then with convertAndSendToUser send changes to current user.
// Example of how to send a message to the user using the sessionId
String response = "This could also be one of your product objects of type Product";
SimpMessageHeaderAccessor headerAccessor = SimpMessageHeaderAccessor.create(SimpMessageType.MESSAGE);
headerAccessor.setSessionId(sessionId);
headerAccessor.setLeaveMutable(true);
messagingTemplate.convertAndSendToUser(sessionId,"/queue/product/changes", response, headerAccessor.getMessageHeaders());
}
}
Изменение клиентской подписки
stompClient.subscribe('/user/queue/product/changes', function (scoredata) {
// We received product changes
});
Для получения подробной информации вы также можете проверить этот ответ: https://stackoverflow.com/a/26288475/11133168
Решение 2 (идентификатор основного продукта)
Однако, если вы действительно хотите рассмотреть возможность использования остаточного контроллера, чтобы начать регистрацию вашего процесса, или если он просто не соответствует вашим требованиям, вам следует просмотреть ссылку ниже. Spring также может отслеживать активные сеансы веб-сокетов и их пользователей через открытый компонент SimpUserRegistry. Однако вам потребуется настроить собственный адаптер ChannelInterceptor для входного канала вашего клиента, в зависимости от безопасности ваших приложений, чтобы определить пользователя. Проверьте этот ответ для получения подробной информации и примеров кода: https://stackoverflow.com/a/45359294/11133168
Решение 3 (темы с идентификаторами продуктов)
Вы также можете подписаться на определенную тему идентификатора продукта, поэтому вам даже не нужно знать, какой пользователь хочет получать уведомления об изменениях для конкретного продукта.
Изменение клиентской подписки
//e.g if you want to be notified about changes for products with id 5
stompClient.subscribe('/product/changes/5', function (scoredata) {
// We received product changes
});
Пример службы сервера
@Service
public class WebSocketProductService{
@Autowired
private SimpMessagingTemplate simpMessagingTemplate;
// This would be the method which should inform your clients about specific product
// changes, instead of the String parameters a Product object should be used instead,
// you have to call this method yourself on product changes or schedule it or sth.
public void sendProductChange(String product, String productId) {
this.simpMessagingTemplate.convertAndSend("/product/changes/"+productId, product);
}
}
Контроллер сервера
Требуется, если вы хотите управлять списком подписок на идентификаторы продуктов. Как объяснялось в решении 1, вам нужен класс с аннотацией @Controller, который содержит метод с аннотацией @SubscribeMapping. Этот метод вызывается, если клиент пытается подписаться на указанный путь.
@Controller
public class WebSocketContoller{
@SubscribeMapping("/product/changes/{productId}")
public void productIdSubscription(@DestinationVariable Long productId) {
//Manage your product id subscription list e.g.
}
}
person
FlorianDe
schedule
01.03.2019