Spring WebSocket - 通知订阅者不起作用
Spring WebSocket - notifying subscribers is not working
我正在尝试让 Spring Websockets (Spring 4) 在我一直从事的项目中工作。到目前为止,我已经打开了 Websocket,添加了订阅者并发送了消息。
从昨天开始,我一直在试图弄清楚为什么我的端点不处理由我的 HTML 中包含的 stomp 客户端发送的消息。控制台实际上也没有错误(好吧,我不是 100% 确定 "connected to server undefined" 这里的意思)。
这是 Chrome 控制台的输出:
Opening Web Socket...
Web Socket Opened...
>>> CONNECT
accept-version:1.1,1.0
heart-beat:10000,10000
<<< CONNECTED
version:1.1
heart-beat:0,0
user-name:xxx@yyy.com
connected to server undefined
Connected: CONNECTED
user-name:xxx@yyy.com
heart-beat:0,0
version:1.1
>>> SUBSCRIBE
id:sub-0
destination:/my-project/notify-open-documents/1
Sending message : {"documentId":"1"}
>>> SEND
destination:/my-project/ws/lock-document
content-length:19
{"documentId":"1"}
这是我的代码:
配置:
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableSimpleBroker("/notify-open-documents");
registry.setApplicationDestinationPrefixes("/ws");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) {
stompEndpointRegistry.addEndpoint("/lock-document");
stompEndpointRegistry.addEndpoint("/lock-document").withSockJS();
}
}
控制器:
@Controller
public class DocumentWebsocketController {
@MessageMapping("/lock-document")
@SendTo("/notify-open-documents/{id}")
public Response response(@DestinationVariable("id") Long id, Message message) {
return new Response(message.getDocumentId());
}
}
和我的 HTML 的 STOMP 相关部分:
<script type="text/javascript">
$(document).ready(function() {
connect();
});
var stompClient = null;
function connect() {
var socket = new SockJS('<spring:url value="/lock-document"/>');
stompClient = Stomp.over(socket);
stompClient.connect({}, function (frame) {
console.log('Connected: ' + frame);
stompClient.subscribe('<spring:url value="/notify-open-documents/${id}"/>', function (messageOutput) {
console.log('Receiving message: ' + JSON.parse(messageOutput.body));
});
sendName();
});
}
function disconnect() {
if (stompClient !== null) {
stompClient.disconnect();
}
console.log("Disconnected");
}
function sendName() {
console.log("Sending message : " + JSON.stringify({'documentId' : "${id}" }));
stompClient.send('<spring:url value="/ws/lock-document"/>', {}, JSON.stringify({'documentId': "${id}"}));
}
</script>
我真的 运行 不知道可能出了什么问题,我的浏览器支持 WebSockets,从我在日志中看到的,WebSocket 正在正确打开,消息正在发送,但我能'弄清楚为什么我的控制器无法处理传入的消息。
从您的 HTML 片段中,我看到您正在使用 spring:url
标签生成 STOMP 目的地。 spring:url
标签添加了对 STOMP 目标没有意义的上下文路径。
您正在配置的应用程序目标前缀是 /ws
,代理目标前缀 /notify-open-documents
、none 将匹配您的上下文路径 /my-project
(来自你的控制台输出)。从订阅目的地和发送消息时删除上下文路径(不是从 SockJS URL):
stompClient.send('/ws/lock-document', {}, JSON.stringify({'documentId': "${id}"}));
我正在尝试让 Spring Websockets (Spring 4) 在我一直从事的项目中工作。到目前为止,我已经打开了 Websocket,添加了订阅者并发送了消息。
从昨天开始,我一直在试图弄清楚为什么我的端点不处理由我的 HTML 中包含的 stomp 客户端发送的消息。控制台实际上也没有错误(好吧,我不是 100% 确定 "connected to server undefined" 这里的意思)。
这是 Chrome 控制台的输出:
Opening Web Socket...
Web Socket Opened...
>>> CONNECT
accept-version:1.1,1.0
heart-beat:10000,10000
<<< CONNECTED
version:1.1
heart-beat:0,0
user-name:xxx@yyy.com
connected to server undefined
Connected: CONNECTED
user-name:xxx@yyy.com
heart-beat:0,0
version:1.1
>>> SUBSCRIBE
id:sub-0
destination:/my-project/notify-open-documents/1
Sending message : {"documentId":"1"}
>>> SEND
destination:/my-project/ws/lock-document
content-length:19
{"documentId":"1"}
这是我的代码:
配置:
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableSimpleBroker("/notify-open-documents");
registry.setApplicationDestinationPrefixes("/ws");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) {
stompEndpointRegistry.addEndpoint("/lock-document");
stompEndpointRegistry.addEndpoint("/lock-document").withSockJS();
}
}
控制器:
@Controller
public class DocumentWebsocketController {
@MessageMapping("/lock-document")
@SendTo("/notify-open-documents/{id}")
public Response response(@DestinationVariable("id") Long id, Message message) {
return new Response(message.getDocumentId());
}
}
和我的 HTML 的 STOMP 相关部分:
<script type="text/javascript">
$(document).ready(function() {
connect();
});
var stompClient = null;
function connect() {
var socket = new SockJS('<spring:url value="/lock-document"/>');
stompClient = Stomp.over(socket);
stompClient.connect({}, function (frame) {
console.log('Connected: ' + frame);
stompClient.subscribe('<spring:url value="/notify-open-documents/${id}"/>', function (messageOutput) {
console.log('Receiving message: ' + JSON.parse(messageOutput.body));
});
sendName();
});
}
function disconnect() {
if (stompClient !== null) {
stompClient.disconnect();
}
console.log("Disconnected");
}
function sendName() {
console.log("Sending message : " + JSON.stringify({'documentId' : "${id}" }));
stompClient.send('<spring:url value="/ws/lock-document"/>', {}, JSON.stringify({'documentId': "${id}"}));
}
</script>
我真的 运行 不知道可能出了什么问题,我的浏览器支持 WebSockets,从我在日志中看到的,WebSocket 正在正确打开,消息正在发送,但我能'弄清楚为什么我的控制器无法处理传入的消息。
从您的 HTML 片段中,我看到您正在使用 spring:url
标签生成 STOMP 目的地。 spring:url
标签添加了对 STOMP 目标没有意义的上下文路径。
您正在配置的应用程序目标前缀是 /ws
,代理目标前缀 /notify-open-documents
、none 将匹配您的上下文路径 /my-project
(来自你的控制台输出)。从订阅目的地和发送消息时删除上下文路径(不是从 SockJS URL):
stompClient.send('/ws/lock-document', {}, JSON.stringify({'documentId': "${id}"}));