【问题标题】:Spring websockets not receiving dataSpring websockets不接收数据
【发布时间】:2018-01-25 13:25:19
【问题描述】:

我正在尝试使用 spring websockets,但由于某种我不明白的原因,我可以与服务器建立连接,但是当我发送数据时没有任何反应。

这是我的 Config 类(完全等同于其他 spring websocket 示例):

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketsConfig extends AbstractWebSocketMessageBrokerConfigurer {

@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
    config.enableSimpleBroker("/topic");
    config.setApplicationDestinationPrefixes("/app");
}

@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
     registry.addEndpoint("/ws").withSockJS();
}

}

我的控制器,在我确保 spring 初始化它的包中,因为我看到带有 @PostConstruct 注释的 init() 消息。如您所见,我编写了 System.out.println 以在控制台中查看该方法是否触发,但这从未发生过,因此数据永远不会到达控制器:

@Controller
public class MonitorSpring {

@PostConstruct
protected void init() {
    System.out.println("init()");
}

@MessageMapping("/sendmessage")
@SendTo("/topic/message")
public ChatMessage sendMessage(@Payload ChatMessage chatMessage) {
    System.out.println("sendMessage here");
    return chatMessage;
}

@MessageMapping("/adduser")
@SendTo("/topic/user")
public ChatMessage addUser(@Payload ChatMessage chatMessage, SimpMessageHeaderAccessor headerAccessor) {
    System.out.println("addUser here");
    headerAccessor.getSessionAttributes().put("username", chatMessage.getSender());
    return chatMessage;
}

}

最后是我的 JavaScript 客户端,我将在这里只放重要部分:

function connect(event) {
    username = document.querySelector('#name').value.trim();

    if(username) {
        usernamePage.classList.add('hidden');
        chatPage.classList.remove('hidden');

        var socket = new SockJS('https://' + document.location.host + '/ws');
        stompClient = Stomp.over(socket);

        stompClient.connect({}, onConnected, onError);
    }
    event.preventDefault();
}


function onConnected() {
    stompClient.subscribe('/topic/message', onMessageReceived);
    stompClient.subscribe('/topic/user', onMessageReceived);
    stompClient.send("/app/adduser", {}, JSON.stringify({sender: username, type: 'JOIN'}))

    connectingElement.classList.add('hidden');
}

function sendMessage(event) {
    var messageContent = messageInput.value.trim();
    if (messageContent && stompClient) {
        var chatMessage = {
            sender: username,
            content: messageInput.value,
            type: 'CHAT'
        };
        stompClient.send("/app/sendmessage", {}, JSON.stringify(chatMessage));
        messageInput.value = '';
    }
    event.preventDefault();
}

我确实连接并创建了 websocket 没有任何问题,但是当我向服务器发送一些东西时 我在 chrome 控制台中看到此消息,但服务器上没有任何反应:

>>> SEND
destination:/app/sendmessage
content-length:53

{"sender":"user1","content":"message1","type":"CHAT"}

我做错了什么?

【问题讨论】:

    标签: spring stomp spring-websocket sockjs


    【解决方案1】:

    首先,您应该使用implements WebSocketMessageBrokerConfigurer 而不是AbstractWebSocketMessageBrokerConfigurer,因为它已被弃用。

    当你连接到 websocket 时

     var socket = new SockJS('https://' + document.location.host + '/ws');
    

    您应该连接到 http 端点

     var socket = new SockJS('http://' + document.location.host + '/ws');
    

    如果您尝试向 https 发送消息并且没有配置证书,它可能会拒绝您的消息。

    【讨论】:

      【解决方案2】:

      不确定是否还有人面临这些问题。

      对于未来的任何人

      除了TOvidiu的回答,你应该允许跨域标头

      registry.addEndpoint("/ws").setAllowedOrigins("*").withSockJS();

      【讨论】:

        【解决方案3】:

        我会尽力帮助你,我有一个聊天应用程序,用户不仅可以聊天,还可以上传图片,甚至使用 spring 和 stomp 进行预订,因为我可以检查你的代码,但我最终无法找到正确的问题但如果您接受我的建议,我可以建议一些小改动,希望有助于解决您的问题。

            @Override
        public void registerStompEndpoints(StompEndpointRegistry registry) {
             registry.addEndpoint("/ws").withSockJS();
        }
        

        你能把它改成这样吗?

         @Override
        public void registerStompEndpoints(StompEndpointRegistry registry) {
            registry.addEndpoint("/chat").setAllowedOrigins("*").withSockJS();
        }
        

        以及与 JS 中的 stomp 连接的版本

        var socket = new SockJS('https://' + document.location.host + '/ws');
            stompClient = Stomp.over(socket);
        

        你能用这个代码吗?

            function connectToChat(userName) {
            let socket = new SockJS(url + '/chat');
            console.log("socket.name", socket.name)
            console.log("WebSocket.name", WebSocket.name)
            stompClient = Stomp.over(socket);
            console.log("stompClient = ", stompClient)
            stompClient.connect({}, function (frame) {
                console.log('Connected: ' + frame);
                successCallback(userName);
        
            }, () => {
                reconnect(url, successCallback, userName);
            });
        }
        
        function successCallback(userName) {
            stompClient.subscribe("/topic/messages/" + userName, function (response) {
        
                let data = JSON.parse(response.body);
                console.log("data ", data);
        
                if (selectedUser === data.to) {
                    render(data.message, data.from);
                } 
            });
        }
        
        function reconnect(socketUrl, successCallback, userName) {
            let connected = false;
            let reconInv = setInterval(() => {
                //let socket = new WebSocket(url +'/chat')
                let socket = new SockJS(url + '/chat');
                stompClient = Stomp.over(socket);
                stompClient.connect({}, (frame) => {
                    clearInterval(reconInv);
                    connected = true;
                    successCallback(userName);
                }, () => {
                    if (connected) {
                        reconnect(socketUrl, successCallback, userName);
                    }
                });
            }, 3000);
        }
        

        确保您的链接是正确的,我正在使用我的代码

         let socket = new SockJS(url + '/chat');
        

        关于 HTTP 或 HTTPS,如果您使用 stomp,它将了解链接是否使用 SSL。

        最后,第一个用户必须连接到第二个用户,但在您的情况下,您有 2 个链接

         stompClient.subscribe('/topic/message', onMessageReceived);
        stompClient.subscribe('/topic/user', onMessageReceived);
        

        解决此问题,以便套接字可以了解要连接到哪个用户并从聊天中发送消息。

        希望我对您有所帮助,并希望您能解决您的问题。

        最后,让我向您展示要连接的链接的确切配置

        @Configuration
        @EnableWebSocketMessageBroker
        public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
        
            @Override
            public void registerStompEndpoints(StompEndpointRegistry registry) {
                registry.addEndpoint("/chat").setAllowedOrigins("*").withSockJS();
            }
        
            @Override
            public void configureMessageBroker(MessageBrokerRegistry registry) {
                registry.setApplicationDestinationPrefixes("/app").enableSimpleBroker("/topic");
            }
        }
        

        【讨论】:

          【解决方案4】:

          试试这个

          var socket = new SockJS('/ws');
          

          这对我有用

          【讨论】:

            猜你喜欢
            • 2020-05-01
            • 2023-02-11
            • 2019-12-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-11-13
            • 1970-01-01
            • 2017-03-28
            相关资源
            最近更新 更多