WebSocket与MongoDB集成时GenericMessage处理失败问题排查
问题描述
我开发了一个支持多用户输入、单个终端用户接收所有消息的简易聊天服务,编写了以下相关类和配置,运行后Spring Boot抛出错误,且MongoDB未生成预期集合,浏览器控制台仅显示订阅日志无报错。
后端代码
ChatUserService 类
@Service public class ChatUserService { private final ChatUserRepository chatUserRepository; @Autowired public ChatUserService(ChatUserRepository chatUserRepository) { this.chatUserRepository = chatUserRepository; } public void saveChatUser(ChatUser chatUser){ chatUser.setStatus(Status.ONLINE); chatUserRepository.save(chatUser); } public void disconnect(ChatUser chatUser){ var connectedChatUser = chatUserRepository.findById(chatUser.getEmail()) .orElse(null); if(connectedChatUser != null){ connectedChatUser.setStatus(Status.OFFLINE); chatUserRepository.save(connectedChatUser); } } public List<ChatUser> findConnectedChatUsers(){ return chatUserRepository.findAllByStatus(Status.ONLINE); } }
UserController 类
@Controller public class UserController { private final ChatUserService chatUserService; @Autowired public UserController(ChatUserService chatUserService) { this.chatUserService = chatUserService; } @MessageMapping("user.addUser") @SendTo("/user/topic") public ChatUser addUser(@Payload ChatUser chatUser){ chatUserService.saveChatUser(chatUser); return chatUser; }
WebSocket 配置类
@Configuration @EnableWebSocketMessageBroker public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { @Override public void configureMessageBroker(MessageBrokerRegistry registry) { registry.enableSimpleBroker("/user"); registry.setApplicationDestinationPrefixes("/app"); registry.setUserDestinationPrefix("/user"); } @Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/ws").withSockJS(); } @Override public boolean configureMessageConverters(List<MessageConverter> messageConverters) { var resolver = new DefaultContentTypeResolver(); resolver.setDefaultMimeType(MimeTypeUtils.APPLICATION_JSON); var converter = new MappingJackson2MessageConverter(); converter.setObjectMapper(new ObjectMapper()); converter.setContentTypeResolver(resolver); messageConverters.add(converter); return false; } }
客户端代码
async function connect(event){ email = await fetchAdminEmail() const socket = new SockJS('/ws'); stompClient = Stomp.over(socket); stompClient.connect({},onConnected,onError); event.preventDefault(); } function onConnected() { stompClient.subscribe(`/user/${email}/queue/messages`, onMessageReceived); stompClient.subscribe(`/user/public`, onMessageReceived); stompClient.send('/app/user.addUser', {}, JSON.stringify({email: email,status:'ONLINE'}) ); findAndDisplayConnectedUsers().then(); } async function findAndDisplayConnectedUsers(){ const connectedUserResponse = await fetch('/users'); let connectedUsers = await connectedUserResponse.json(); connectedUsers = connectedUsers.filter(user => user.email !== email); const connectedUsersList = document.querySelector('#connectedUsers'); connectedUsersList.innerHTML = ''; connectedUsers.forEach(user => { appendUserElement(user, connectedUsersList); if (connectedUsers.indexOf(user) < connectedUsers.length-1){ const separator = document.createElement('li'); separator.classList.add('separator'); connectedUsersList.appendChild(separator); } }); } function appendUserElement(user, connectedUsersList) { const listItem = document.createElement('li'); listItem.classList.add('user-item'); listItem.id = user.email; const emailSpan = document.createElement('span'); emailSpan.textContent = user.email; const receivedMessages = document.createElement('span'); receivedMessages.textContent = ''; receivedMessages.classList.add('nbr-msg','hidden'); listItem.append(emailSpan); listItem.append(receivedMessages); connectedUsersList.appendChild(listItem); } async function fetchAdminEmail(){ try{ const repsonse = await fetch('/admin'); const data = await repsonse.json(); return data.email; } catch (error){ console.error("error: ",error); return null; } } document.addEventListener('DOMContentLoaded',function (){ connect(event); });
错误日志
Failed to handle GenericMessage [payload=byte[47], headers={simpMessageType=MESSAGE, conversionHint=method 'addUser' parameter -1, contentType=application/json, simpSessionId=xmuzd12r, simpDestination=/user/topic}] to org.springframework.messaging.support.ExecutorSubscribableChannel$SendTask@3ad5d640 in UserDestinationMessageHandler[DefaultUserDestinationResolver[prefix=/user/]]
问题疑点
怀疑是MongoDB配置问题,因为预期创建的集合并未生成。
内容的提问来源于stack exchange,提问作者Hubert Kiszka
相关产品推荐
相关产品推荐

