stompjs xhr_streaming 超时
stompjs xhr_streaming timeout
我在 angular(1.5.x) 中使用 SockJS + stomp 客户端与 spring (mvc) 服务器建立 websocket。除此以外一切正常:如果我终止服务器,stomp 客户端最多需要两分钟才能检测到浏览器上的连接错误。有没有办法管理更短(或立即)的超时或在服务器死机或断开连接时立即抛出事件?
function socketService($rootScope, $q, $log, $timeout, URL) {
var listener = $q.defer(),
socket = {
client: null,
stomp: null
};
var reconnect = function() {
$log.info('Reconnecting');
$timeout(function() {
initialize();
}, 2000);
};
var getMessage = function(data) {
var message = JSON.parse(data), out = {};
out.message = message;
if (message.metadata) {
out.time = new Date(message.metadata.timestamp);
}
$log.info(out);
return out;
};
var startListener = function() {
$log.info('Connected');
socket.stomp.subscribe(URL.PROCESS_UPDATES, function(data) {
listener.notify(getMessage(data.body));
});
socket.stomp.subscribe(URL.CONTAINER_UPDATES, function(data) {
listener.notify(getMessage(data.body));
});
$rootScope.$broadcast('web_socket_event', 'CONNECTED');
};
var errorCallback = function (error) {
// Browser gets here 2 minutes after the server is killed. Seems like might be affected by the the xhr_streaming timeout
$rootScope.$broadcast('web_socket_event', 'DISCONNECTED');
reconnect();
};
return {
initialize: initialize,
receive: receive
};
function initialize() {
var header = {
'accept-version': 1.1
};
$log.info('Connecting');
// custom header to specify version.
socket.client = new SockJS(header, URL.ROOT + URL.UPDATES);
socket.client.debug = function(){};
socket.stomp.heartbeat.outgoing = 0;
socket.stomp.heartbeat.incoming = 2000;
socket.stomp = Stomp.over(socket.client);
socket.stomp.connect({}, startListener, errorCallback);
socket.stomp.onerror = errorCallback;
socket.stomp.onclose = reconnect;
};
function receive() {
return listener.promise;
};
}
**// browser console:**
Opening Web Socket...
stomp.js:145 Web Socket Opened...
stomp.js:145 >>> CONNECT
accept-version:1.1,1.0
heart-beat:0,2000
stomp.js:145 <<< CONNECTED
version:1.1
heart-beat:2000,0
stomp.js:145 connected to server undefined
stomp.js:145 check PONG every 2000ms
我不是 WS 方面的专家,但根据我们通过问题评论进行的对话,以及我对 WS 的理解,很明显您的服务器正在与 NO heart 协商连接-节拍:heart-beat 0,0
。第一个 0 是客户端应该完全不期望来自服务器的数据包的最长时间(以毫秒为单位)(当此超时过去并且任何一方根本没有通信时服务器应该发送心跳帧),第二个 0 是等效但从服务器的角度来看。
您应该将您的服务器设置为定期发送心跳,并期待来自客户端的心跳。通过这种方式,您可以让您的服务器和客户端更好地管理 WS 连接资源,并且还可以确保在应用停滞连接检测策略或任何其他机制时,连接不会被 'network' 断开。
我不知道您是如何设置 WS 服务器的,但下面的示例适用于 spring 引导中的简单 WS 服务器:
import org.springframework.beans.factory.annotation.Value;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
@Component
public class WebSocketConfigurer extends AbstractWebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
long heartbeatServer = 10000; // 10 seconds
long heartbeatClient = 10000; // 10 seconds
ThreadPoolTaskScheduler ts = new ThreadPoolTaskScheduler();
ts.setPoolSize(2);
ts.setThreadNamePrefix("wss-heartbeat-thread-");
ts.initialize();
config.enableSimpleBroker("/topic")
.setHeartbeatValue(new long[]{heartbeatServer, heartbeatClient})
.setTaskScheduler(ts);
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/my/ws/endpoint")
.setAllowedOrigins("*")
.withSockJS();
}
}
我在 angular(1.5.x) 中使用 SockJS + stomp 客户端与 spring (mvc) 服务器建立 websocket。除此以外一切正常:如果我终止服务器,stomp 客户端最多需要两分钟才能检测到浏览器上的连接错误。有没有办法管理更短(或立即)的超时或在服务器死机或断开连接时立即抛出事件?
function socketService($rootScope, $q, $log, $timeout, URL) {
var listener = $q.defer(),
socket = {
client: null,
stomp: null
};
var reconnect = function() {
$log.info('Reconnecting');
$timeout(function() {
initialize();
}, 2000);
};
var getMessage = function(data) {
var message = JSON.parse(data), out = {};
out.message = message;
if (message.metadata) {
out.time = new Date(message.metadata.timestamp);
}
$log.info(out);
return out;
};
var startListener = function() {
$log.info('Connected');
socket.stomp.subscribe(URL.PROCESS_UPDATES, function(data) {
listener.notify(getMessage(data.body));
});
socket.stomp.subscribe(URL.CONTAINER_UPDATES, function(data) {
listener.notify(getMessage(data.body));
});
$rootScope.$broadcast('web_socket_event', 'CONNECTED');
};
var errorCallback = function (error) {
// Browser gets here 2 minutes after the server is killed. Seems like might be affected by the the xhr_streaming timeout
$rootScope.$broadcast('web_socket_event', 'DISCONNECTED');
reconnect();
};
return {
initialize: initialize,
receive: receive
};
function initialize() {
var header = {
'accept-version': 1.1
};
$log.info('Connecting');
// custom header to specify version.
socket.client = new SockJS(header, URL.ROOT + URL.UPDATES);
socket.client.debug = function(){};
socket.stomp.heartbeat.outgoing = 0;
socket.stomp.heartbeat.incoming = 2000;
socket.stomp = Stomp.over(socket.client);
socket.stomp.connect({}, startListener, errorCallback);
socket.stomp.onerror = errorCallback;
socket.stomp.onclose = reconnect;
};
function receive() {
return listener.promise;
};
}
**// browser console:**
Opening Web Socket...
stomp.js:145 Web Socket Opened...
stomp.js:145 >>> CONNECT
accept-version:1.1,1.0
heart-beat:0,2000
stomp.js:145 <<< CONNECTED
version:1.1
heart-beat:2000,0
stomp.js:145 connected to server undefined
stomp.js:145 check PONG every 2000ms
我不是 WS 方面的专家,但根据我们通过问题评论进行的对话,以及我对 WS 的理解,很明显您的服务器正在与 NO heart 协商连接-节拍:heart-beat 0,0
。第一个 0 是客户端应该完全不期望来自服务器的数据包的最长时间(以毫秒为单位)(当此超时过去并且任何一方根本没有通信时服务器应该发送心跳帧),第二个 0 是等效但从服务器的角度来看。
您应该将您的服务器设置为定期发送心跳,并期待来自客户端的心跳。通过这种方式,您可以让您的服务器和客户端更好地管理 WS 连接资源,并且还可以确保在应用停滞连接检测策略或任何其他机制时,连接不会被 'network' 断开。
我不知道您是如何设置 WS 服务器的,但下面的示例适用于 spring 引导中的简单 WS 服务器:
import org.springframework.beans.factory.annotation.Value;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
@Component
public class WebSocketConfigurer extends AbstractWebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
long heartbeatServer = 10000; // 10 seconds
long heartbeatClient = 10000; // 10 seconds
ThreadPoolTaskScheduler ts = new ThreadPoolTaskScheduler();
ts.setPoolSize(2);
ts.setThreadNamePrefix("wss-heartbeat-thread-");
ts.initialize();
config.enableSimpleBroker("/topic")
.setHeartbeatValue(new long[]{heartbeatServer, heartbeatClient})
.setTaskScheduler(ts);
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/my/ws/endpoint")
.setAllowedOrigins("*")
.withSockJS();
}
}