我尝试弹簧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"}
我可能做错了什么?
答案 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');
这对我有用