Spring websockets没有接收数据

时间:2018-01-25 13:25:19

标签: spring stomp spring-websocket sockjs

我尝试弹簧websockets,由于某些原因我不明白,我可以与服务器建立连接,但是当我发送数据时没有任何反应。

这是我的Config类(exatcly等于其他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();
}

}

我的控制器,在一个包中,我确保它是弹性的,就像我带有@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"}

我可能做错了什么?

4 个答案:

答案 0 :(得分:0)

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

连接到网络套接字时

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

您应该连接到http端点

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

如果您尝试将消息发送到https并且未配置证书,则可能会拒绝您的消息。

答案 1 :(得分:0)

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

面向未来的任何人

除了TOvidiu的答案,您还应该允许跨域标头

registry.addEndpoint(“ / ws”)。setAllowedOrigins(“ *”)。withSockJS();

答案 2 :(得分:0)

我将尝试为您提供帮助,我有一个聊天应用程序,用户不仅可以聊天,还可以上传图片,甚至可以使用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");
    }
}

答案 3 :(得分:-1)

尝试

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

这对我有用