简体   繁体   中英

Spring boot's convertAndSendToUser not working

I'm new to Spring boot and trying to learn it. I'm following a tutorial on how to make a simple one-to-one chat app.

Everything is working fine except that messages aren't getting sent between users. Messages get from the sender to the server but when convertAndSentToUser() nothing gets to the other client (recipient).

Here's the message broker configuration:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketMessageBrokerConfig implements WebSocketMessageBrokerConfigurer {
    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/user");
        config.enableSimpleBroker("/topic", "/queue");
        config.setApplicationDestinationPrefixes("/app");
        config.setUserDestinationPrefix("/user");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/broadcast");
        registry.addEndpoint("/broadcast").withSockJS().setHeartbeatTime(60_000);
        registry.addEndpoint("/chat").withSockJS();
    }

    @Override
    public void configureClientInboundChannel(ChannelRegistration registration) {
        registration.interceptors(new UserInterceptor());
    }
}

And the controller that handles new connections:

@RestController
@Log4j2
public class WebSocketConnectionRestController {
    
    @Autowired
    private ActiveUserManager activeSessionManager;
    
    ...

    @PostMapping("/rest/user-connect")
    public String userConnect(HttpServletRequest request, @ModelAttribute("username") String userName) {
        String remoteAddr = "";
        if (request != null) {
            remoteAddr = request.getHeader("Remote_Addr");
            if (remoteAddr == null || remoteAddr.isEmpty()) {
                remoteAddr = request.getHeader("X-FORWARDED-FOR");
                if (remoteAddr == null || "".equals(remoteAddr)) {
                    remoteAddr = request.getRemoteAddr();
                }
            }
        }

        log.info("registered " + userName + " " + remoteAddr);
        activeSessionManager.add(userName, remoteAddr);
        return remoteAddr;
    }


   ...

}

Finally, here's the controller that handles new messages:

@Controller
@Log4j2
public class WebSocketChatController implements ActiveUserChangeListener {
    @Autowired
    private SimpMessagingTemplate webSocket;

    ...
    
    @MessageMapping("/chat")
    public void send(@Payload ChatMessage chatMessage) throws Exception {
        ChatMessage message = new ChatMessage(chatMessage.getFrom(), chatMessage.getText(), chatMessage.getRecipient());
        log.info("sent message to " + chatMessage.getRecipient());
        webSocket.convertAndSendToUser(chatMessage.getRecipient(), "/queue/messages", message);
    }

    ...

}

I finally found the problem. The tutorial had a UserInterceptor which links the session id for new connections to the username but it was trying to cast an Arraylist to a LinkedList so I just casted it to a List instead:

public class UserInterceptor implements ChannelInterceptor {
    
    @Override
    public Message<?> preSend(Message<?> message, MessageChannel channel) {
        StompHeaderAccessor accessor
                = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);

        if (StompCommand.CONNECT.equals(accessor.getCommand())) {

            Object raw = message
                    .getHeaders()
                    .get(SimpMessageHeaderAccessor.NATIVE_HEADERS);

            if (raw instanceof Map) {
                Object name = ((Map) raw).get("username");
                if (name instanceof List) {
                    accessor.setUser(new User(((List) name).get(0).toString()));
                }
            }
        }

        return message;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM