#javascript #java #spring #websocket
Пишу чат на вебсокетах. Использую sockjs.js и stomp.js. Соединение проходит успешно,
сабскрайб на рассылку тоже. Но при попытке отправить на бекенд сообщение (для рассылки
всем присоеденившимся к чату) на нужный контролллер ничего не приходит, хотя в консоль
либа пишет что данные отправила:
>>> SEND
destination:/app/app-dest-prefix/chat
content-length:76
{"from":"Lesha","text":"message","timeCreation":"2017-10-12T15:26:29.410Z"}
так я присоединяюсь
stompClient = Stomp.over(new SockJS("/ContactBook/app/cbxSoc"));
так сабскрайблюсь:
stompClient.subscribe('/topic/messages', function (message) {
console.log(message);
});
так я отправляю сообщение:
stompClient.send("/app-dest-prefix/chat", {}, JSON.stringify({'from':'Lesha', 'text':$scope.chatInput,
'timeCreation':new Date()})
такой у меня контроллер
@Controller
public class ChatController {
@MessageMapping("/chat")
@SendTo("/topic/messages")
public Message send(Message message){
String time = new SimpleDateFormat("HH:mm").format(new Date());
message.setTimeCreation(time);
return message;
}
}
такая конфигурация:
@Configuration
@EnableWebSocketMessageBroker
public class CbxSocketConfig extends AbstractWebSocketMessageBrokerConfigurer{
@Override
public void registerStompEndpoints(StompEndpointRegistry ser) {
ser.addEndpoint("/cbxSoc").withSockJS();
}
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
// Prefix for messages FROM client TO server
config.setApplicationDestinationPrefixes("/app-dest-prefix");
// Prefix for messages FROM server TO client
config.enableSimpleBroker("/events", "/topic", "/queue");
config.setUserDestinationPrefix("/user");
}
}
Подскажите, кто в курсе, где я ошибся. Спасибо. Такое ощущение, что урл не верный
указал, но судя по документации всё правильно...
UPD
Может кто-то знает как отхендлить вообще всё. что приходит от клиента (не только
по определённому пути, который указана в @MessageMapping("/chat"))?
UPD2
Добавил хендлер для отлавливания вообще всех сообщению вебсокета
@Override
public void configureClientInboundChannel(ChannelRegistration registration)
{
registration.setInterceptors(new MyChannelInterceptor());
}
public class MyChannelInterceptor extends ChannelInterceptorAdapter {
@Override
public Message preSend(Message message, MessageChannel channel) {
StompHeaderAccessor accessor = StompHeaderAccessor.wrap(message);
//StompCommand command = accessor.getStompCommand();
return message;
}
}
При отправке клиентом сообщения этот хендлер его отлавливает, но на контроллер всё
равно не доходит..
UPD3 пример лог мапинга
2017-10-22 20:30:19 INFO RequestMappingHandlerMapping:220 - Mapped "{[/client/managers],methods=[GET],params=[],headers=[],consumes=[],produces=[application/json],custom=[]}"
onto public java.util.List com.miroktell.contactbook.controllers.ClientController.getManagers()
2017-10-22 20:30:19 INFO RequestMappingHandlerMapping:220 - Mapped "{[/client/filter],methods=[POST],params=[],headers=[],consumes=[],produces=[application/json],custom=[]}"
onto public com.miroktell.contactbook.containers.RowsContainer com.miroktell.contactbook.controllers.ClientController.getClientsByFilter(com.miroktell.contactbook.containers.ClientListFilter)
throws java.io.IOException
2017-10-22 20:30:19 INFO RequestMappingHandlerMapping:220 - Mapped "{[/client/getFullClientByPhoneNumber],methods=[GET],params=[],headers=[],consumes=[],produces=[application/json],custom=[]}"
onto public com.miroktell.contactbook.model.Client com.miroktell.contactbook.controllers.ClientController.getFullClientByPhoneNumber(java.lang.String)
2017-10-22 20:30:19 INFO RequestMappingHandlerMapping:220 - Mapped "{[/client/addNotice],methods=[POST],params=[],headers=[],consumes=[],produces=[application/json],custom=[]}"
onto public com.miroktell.contactbook.utils.MyMesage com.miroktell.contactbook.controllers.ClientController.addNotice(com.miroktell.contactbook.model.ClientNotice)
2017-10-22 20:30:19 INFO RequestMappingHandlerMapping:220 - Mapped "{[/util/filter/delete/{id}],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}"
onto public com.miroktell.contactbook.utils.MyMesage com.miroktell.contactbook.controllers.UtilController.deleteFilter(int)
2017-10-22 20:30:19 INFO SimpleUrlHandlerMapping:315 - Mapped URL path [/**] onto
handler of type [class org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler]
2017-10-22 20:30:19 INFO RequestMappingHandlerAdapter:523 - Looking for @ControllerAdvice:
WebApplicationContext for namespace 'dispatcher-servlet': startup date [Sun Oct 22
20:30:18 EEST 2017]; parent: Root WebApplicationContext
Ответы
Ответ 1
1) Вы отсылаете JSON строку, соответственно вы должны прописать в конструкторе соответствующие аннотация для разбора данных 2) Не работал с этой веткой АПИ, но мне кажется Вам стоит поиграться с конфигурацией, а именно enableSimpleBroker("/events", "/topic", "/queue") .У Вас неявно указана ссылка, по которой контроллер должен считывать данные. В Вашем же случаи это должно быть @MessageMapping("/app-dest-prefix/chat"). ПробуйтеОтвет 2
Проблема осталась не решенной. Вышел из ситуации (пока не разберусь) таким образом. Сообщение на бэкенд отправляю через обычный http, а уже рассылку всем сабскрайберам осуществляю через вебсокет. @RequestMapping(value = "/testChat", method = RequestMethod.POST, headers="Accept=application/json") public void testChat(@RequestBody Message message){ Logger.getLogger(NotificationController.class.getName()).log(Level.SEVERE, "RECEIVED MESSAGE FROM CLIENT: \n"+message); this.simpMessagingTemplate.convertAndSend("/topic/messages", message); Logger.getLogger(NotificationController.class.getName()).log(Level.SEVERE, "SENDED THIS MESSAGE TO ALL SUBSCRIBERS: /topic/messages"); } Понимаю что так делать - полный бред, но пока проблема не решена, это вроде как единственный рабочий способ...Спасибо @GenCloud за попытку помочь.
Комментариев нет:
Отправить комментарий