这可能是重复的:
Websocket - InvalidStateError: The connection has not been established yet。
我正在实施通知系统。并希望在用户登录时初始化Socket连接,并向他显示他的通知,以及是否发生某些事件。
我的代码段如下。
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;
}
}
部分代码 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}');
});
为什么 Firefox控制台在网络标签状态代码为XML Parsing Error: no root element found Location:
时提供200 OK
。
网络标签
答案 0 :(得分:2)
原始发布到this question。
这是因为stompClient.connect()
方法是异步的。在建立连接之前,我不会暂停执行。在getNotifications()
之后立即呼叫alert()
时,很可能还没有建立连接(如果alert()
需要足够的时间来连接,则可能会建立连接)。
您应该在getNotifications()
回调中调用stompClient.connect()
(就像使用stompClient.subscribe()
一样),以确保在调用连接时建立连接。
例如:
stompClient.connect({}, function( frame ){
console.log( "Connected :- "+frame );
stompClient.subscribe("/topic/notifications", function( notifications ) {
alert( notifications );
});
getNotifications();
}, function( error ) {
alert( error );
});
除此之外,您可以考虑在Java代码中使用@SubscribeMapping
注释来摆脱JavaScript的显式消息,以从服务器获取初始消息。这样,服务器会在订阅建立后立即发送初始消息。
例如:
@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;
}
然后客户端代码如下所示:
stompClient.connect({}, function( frame ){
console.log( "Connected :- "+frame );
stompClient.subscribe("/topic/notifications", function( notifications ) {
alert( notifications );
});
}, function( error ) {
alert( error );
});