Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/403.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript stompjs xhr_流超时_Javascript_Angularjs_Websocket_Spring Websocket_Stompjs - Fatal编程技术网

Javascript stompjs xhr_流超时

Javascript stompjs xhr_流超时,javascript,angularjs,websocket,spring-websocket,stompjs,Javascript,Angularjs,Websocket,Spring Websocket,Stompjs,我正在angular(1.5.x)中使用SockJS+stomp客户端来建立带有spring(mvc)服务器的websocket。除此之外,所有这些都可以正常工作:如果我关闭服务器,stomp客户端最多需要两分钟才能检测到浏览器上的连接错误。有没有办法在服务器死机或断开连接时管理更短(或立即)的超时或抛出事件 function socketService($rootScope, $q, $log, $timeout, URL) { var listener = $q.defer(),

我正在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
函数socketService($rootScope、$q、$log、$timeout、URL){
var listener=$q.defer(),
插座={
客户机:空,
跺脚:空
};
var=function(){
$log.info('重新连接');
$timeout(函数(){
初始化();
}, 2000);
};
var getMessage=函数(数据){
var message=JSON.parse(数据),out={};
out.message=消息;
if(message.metadata){
out.time=新日期(message.metadata.timestamp);
}
$log.info(输出);
返回;
};
var startListener=函数(){
$log.info('Connected');
socket.stomp.subscribe(URL.PROCESS\u更新,函数(数据){
notify(getMessage(data.body));
});
socket.stomp.subscribe(URL.CONTAINER\u更新,函数(数据){
notify(getMessage(data.body));
});
$rootScope.$broadcast('web_socket_event','CONNECTED');
};
var errorCallback=函数(错误){
//浏览器在服务器关闭2分钟后到达这里。似乎可能会受到xhr\U流超时的影响
$rootScope.$broadcast('web_socket_event','DISCONNECTED');
重新连接();
};
返回{
初始化:初始化,
接收:接收
};
函数初始化(){
变量头={
“接受版本”:1.1
};
$log.info('Connecting');
//自定义标题以指定版本。
socket.client=newsockjs(头,URL.ROOT+URL.UPDATES);
socket.client.debug=函数(){};
socket.stomp.heartbeat.outing=0;
socket.stomp.heartbeat.incoming=2000;
socket.stomp=stomp.over(socket.client);
socket.stomp.connect({},startListener,errorCallback);
socket.stomp.onerror=errorCallback;
socket.stomp.onclose=重新连接;
};
函数receive(){
回报你的承诺;
};
}
**//浏览器控制台:**
正在打开Web套接字。。。
js:145 Web套接字已打开。。。
stomp.js:145>>>连接
接受版本:1.1,1.0
心跳:02000

stomp.js:145我不是WS方面的专家,但根据我们通过问题评论进行的对话,以及我对WS的理解,很明显,您的服务器正在协商与无心跳的连接:
心跳0,0
。第一个0是客户端根本不希望从服务器收到任何数据包的最长时间(以毫秒为单位)(当此超时时间过去且任何一方都没有通信时,服务器应发送心跳帧),第二个0是等效的,但从服务器的角度来看

您应该将服务器设置为定期发送心跳信号,并期望客户端发送心跳信号。通过这种方式,您可以让服务器和客户端更好地管理WS-connection资源,还可以确保在应用暂停的连接检测策略或任何其他机制时,连接不会被“网络”断开

我不知道您是如何设置WS-server的,但下面的示例适用于spring boot中的一个简单WS-server:

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();
    }
}

您可以发布用于创建连接的javascript代码吗?您是否订阅了连接错误事件的回调函数?@artemisian请查看上面的代码,谢谢!请添加
socket.client.debug=function(msg){console.log(msg)}并检查心跳协商(在控制台中搜索心跳)?此外,如果在服务器运行时打印了任何消息disconnects@artemisian我加了一句,但从来没有人叫过。杀了服务器两分钟后,我听到一声“哎哟!与…的连接中断。。。“由stompjs调用的浏览器控制台信息消息:145:108。有关协商的信息如何。在ws-connection框架的网络面板中签入开发人员工具,以便将客户端设置为期望心跳,这是我可以通过stompJS/SockJS实现的还是必须通过angular http协议实现的?客户端发送心跳建议,但服务器将对心跳协商条款有最终决定权。你的spring配置也是如此,它将设置心跳计时,因为我已经将所有心跳的东西连接起来并工作;但是,在浏览器(Safari技术预览版)控制台上,我可以看到以下错误:“不兼容的SockJS!主站点使用:“1.1.2”,iframe使用“1.0.0”。在ff/Chrome中,错误是:“握手响应之前关闭websocket连接…”。此错误是间歇性的。有什么想法吗?听起来像是sockjs客户端/服务器的版本控制问题,请检查浏览器中的调试日志。在协商版本的同一步骤中,也会协商版本控制,您的客户端将告诉服务器它接受的版本
接受版本:1.1,1.0
,然后服务器将响应使用哪个版本
版本:1.1
。确保服务器使用客户端建议的一个版本进行响应。对齐您的版本