spring启动的convertandsendtouser不工作

lvmkulzt  于 2021-07-23  发布在  Java
关注(0)|答案(1)|浏览(474)

我是新来的Sping Boot ,并试图学习它。我正在学习如何制作一个简单的一对一聊天应用程序。
一切正常,只是用户之间没有发送消息。从发送者到服务器的消息 convertAndSentToUser() 其他客户机(收件人)什么也得不到。
以下是message broker配置:

@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());
    }
}

以及处理新连接的控制器:

@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;
    }

   ...

}

最后,这里是处理新消息的控制器:

@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);
    }

    ...

}
3bygqnnd

3bygqnnd1#

我终于找到了问题所在。教程有一个 UserInterceptor 它将新连接的会话id链接到用户名,但它试图将arraylist强制转换为linkedlist,因此我将其强制转换为列表:

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;
    }
}

相关问题