问题描述
这是/可能重复:
网络标签
最初发布于 这个问题.
这是因为 stompClient.connect()
方法是异步的.我不会暂停执行,直到建立连接.当您在 alert()
之后立即调用 getNotifications()
时,很可能还没有建立连接(如果 alert()
需要足够的时间,它可能会建立是时候连接了).
你应该在 stompClient.connect()
回调中调用 getNotifications()
(就像你使用 stompClient.subscribe()
) 以确保在调用时建立连接.
例如:
stompClient.connect({}, function( frame ){console.log("已连接:-"+frame);stompClient.subscribe("/topic/notifications", 函数(通知){警报(通知);});收到通知();}, 函数(错误){警报(错误);});
除此之外,您可以考虑在 Java 代码中使用 @SubscribeMapping
注释来摆脱来自 JavaScript 的显式消息,以从服务器获取初始消息.这样,服务器在订阅建立后立即发送初始消息.
例如:
@MessageMapping(value="/hello")@SubscribeMapping("/通知")@SendTo("/topic/notifications")公共通知你好(){尝试 {线程睡眠(2000);} catch (InterruptedException e) {//TODO 自动生成的 catch 块e.printStackTrace();}通知通知=新通知();notify.setMessage("你好世界!!!");返回通知;}
然后客户端代码将如下所示:
stompClient.connect({}, function( frame ){console.log("已连接:-"+frame);stompClient.subscribe("/topic/notifications", 函数(通知){警报(通知);});}, 函数(错误){警报(错误);});
This is/may be duplicate of:
Websocket - InvalidStateError: The connection has not been established yet.
I am implementing Notification System. And want to initialize Socket connection when user Logged In, and show him his notifications, and also if some event happens.
My Code snippet as follows.
websocket.js :
var stompClient = null;
function connect( temp ) {
alert(temp);
//var socket = new SockJS("/websock");
//var socket = new SockJS("/websock"+temp);
var socket = new SockJS(context_path+"/websock"+temp);
//context_path == "/SupportCenter"
stompClient = Stomp.over(socket);
stompClient.connect({}, function( frame ){
console.log( "Connected :- "+frame );
stompClient.subscribe("/topic/notifications", function( notifications ) {
alert( notifications );
});
}, function( error ) {
alert( error );
});
alert();
getNotifications();
}
function getNotifications() {
stompClient.send("/app/hello", {}, "Hiiiiii");
}
WebSocketConfig.java :
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
/* (non-Javadoc)
* @see org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer#registerStompEndpoints(org.springframework.web.socket.config.annotation.StompEndpointRegistry)
*/
@Override
public void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) {
stompEndpointRegistry.addEndpoint("/websock").withSockJS();
}
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
// TODO Auto-generated method stub
config.enableSimpleBroker("/topic");
config.setApplicationDestinationPrefixes("/app");
}
}
WebSocketController.java :
@Controller
public class WebSocketController {
@MessageMapping(value="/hello")
@SendTo("/topic/notifications")
public Notify hello() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Notify notify = new Notify();
notify.setMessage("Hello World !!!");
return notify;
}
}
Some code Hom.jsp :
<script type="text/javascript" src="<c:url value="/resources/js/sockjs.min.js"/>"></script>
<script type="text/javascript" src="<c:url value="/resources/js/stomp.min.js"/>"></script>
<script type="text/javascript" src="<c:url value="/resources/js/websocket.js"/>"></script>
<script type="text/javascript">
$(document).ready(function() {
//...
connect( '${nsec}');
});
Why Firefox Console giving XML Parsing Error: no root element found Location:
while in Network tab status code is 200 OK
.
Console Tab
Network Tab
Originaly posted to this question.
This is because stompClient.connect()
method is asynchronous. I doesn't pause the execution waiting until connection is established. When you call getNotifications()
right after alert()
most probably connection is not established yet (it might be established if alert()
takes enough time to connect).
You are supposed to call getNotifications()
in stompClient.connect()
callback (just like you do with stompClient.subscribe()
) to be sure that connection is established by the time it gets invoked.
For example:
stompClient.connect({}, function( frame ){
console.log( "Connected :- "+frame );
stompClient.subscribe("/topic/notifications", function( notifications ) {
alert( notifications );
});
getNotifications();
}, function( error ) {
alert( error );
});
Besides of that you may consider using @SubscribeMapping
annotation in your java code to get rid of explicit message from JavaScript to get initial message from the server. This way the server sends initial message as soon as subscription is established.
For example:
@MessageMapping(value="/hello")
@SubscribeMapping("/notifications")
@SendTo("/topic/notifications")
public Notify hello() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Notify notify = new Notify();
notify.setMessage("Hello World !!!");
return notify;
}
Then client code would look like following:
stompClient.connect({}, function( frame ){
console.log( "Connected :- "+frame );
stompClient.subscribe("/topic/notifications", function( notifications ) {
alert( notifications );
});
}, function( error ) {
alert( error );
});
这篇关于如何在 Spring MVC 中正确配置 Stomp 和 SockJS 端点?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!