重新连接到服务器时如何强制 Atmosphere.js 使用首选传输?

Posted

技术标签:

【中文标题】重新连接到服务器时如何强制 Atmosphere.js 使用首选传输?【英文标题】:How to force Atmosphere.js to use the preferred transport when reconnecting to the Server? 【发布时间】:2016-05-05 13:51:16 【问题描述】:

当首选传输失败时,大气会尝试使用备用传输。它试图重新连接 maxReconnect 次数。之后它调用 onClose 和 onError。

当我再次尝试订阅时,Atmosphere 总是使用后备传输进行连接。

这是我的客户端配置:

AtmosphereRequestConfig jsonRequestConfig = // ...
jsonRequestConfig.setTransport(AtmosphereRequestConfig.Transport.WEBSOCKET); 
jsonRequestConfig.setFallbackTransport(AtmosphereRequestConfig.Transport.LONG_POLLING);
jsonRequestConfig.setLogLevel("debug");
jsonRequestConfig.setMaxReconnectOnClose(1);
Atmosphere atmosphere = Atmosphere.create();
clientRequest = atmosphere.subscribe(jsonRequestConfig);

当我的服务器正在运行并且客户端第一次连接(页面重新加载)时,连接在 Websockets 上。然后我停止了我的服务器客户端显示:

atmosphere.js:3252 Sat Jan 30 2016 22:17:14 GMT+0100 (CET) Atmosphere: websocket.onclose
atmosphere.js:3252 Websocket closed, reason: Normal closure; the connection successfully completed whatever purpose for which it was created. - wasClean: true
atmosphere.js:3252 Sat Jan 30 2016 22:17:14 GMT+0100 (CET) Atmosphere: Firing onClose (closed case)
ConsoleLogger.java:32 AtmosphereListener: onClose
atmosphere.js:3252 Sat Jan 30 2016 22:17:14 GMT+0100 (CET) Atmosphere: Request already closed, not firing onClose (closed case)
atmosphere.js:3252 Sat Jan 30 2016 22:17:14 GMT+0100 (CET) Atmosphere: invoking .close() on WebSocket object
atmosphere.js:3252 Sat Jan 30 2016 22:17:14 GMT+0100 (CET) Atmosphere: Firing onReconnect
ConsoleLogger.java:32 AtmosphereListener: onReconnect
atmosphere.js:3252 Sat Jan 30 2016 22:17:14 GMT+0100 (CET) Atmosphere: Firing onReconnect
atmosphere.js:3252 Invoking executeWebSocket, using URL: ws://www.example.com:8080/socket/widget/2418C3F0-9A9B-48C4-8EE3-0541465EEACD%7C%7Crefdgdfgwe324234%7C%7CAF8F7A67-CDD0-4AD3-96C4-D447E970D0F8?X-Atmosphere-tracking-id=f89f00d8-b412-4825-80f9-ac8ca280edb5&X-Atmosphere-Framework=2.3.1-javascript&X-Atmosphere-Transport=websocket&Content-Type=application/json; charset=UTF-8&X-atmo-protocol=true
atmosphere.js:3252 Sat Jan 30 2016 22:17:14 GMT+0100 (CET) Atmosphere: websocket.onopen
atmosphere.js:3252 Websocket successfully opened
atmosphere.js:3252 Sat Jan 30 2016 22:17:15 GMT+0100 (CET) Atmosphere: websocket.onclose
atmosphere.js:3252 Websocket closed, reason: Connection was closed abnormally (that is, with no close frame being sent). - wasClean: false
atmosphere.js:3252 Sat Jan 30 2016 22:17:15 GMT+0100 (CET) Atmosphere: Request already closed, not firing onClose (closed case)
atmosphere.js:3252 Sat Jan 30 2016 22:17:15 GMT+0100 (CET) Atmosphere: Request already closed, not firing onClose (closed case)
atmosphere.js:3252 Sat Jan 30 2016 22:17:15 GMT+0100 (CET) Atmosphere: invoking .close() on WebSocket object
atmosphere.js:3252 Websocket reconnect maximum try reached 2
atmosphere.js:3252 Websocket error, reason: 
atmosphere.js:3252 Sat Jan 30 2016 22:17:15 GMT+0100 (CET) Atmosphere: Firing onError, reasonPhrase: maxReconnectOnClose reached

然后我重新启动了我的服务器。客户端自动重新连接,因为他尝试在onError 中初始化大气连接。这是我得到的日志:

atmosphere.js:1195 WebSocket connection to 'ws://www.example.com:8080/socket/widget/2418C3F0-9A9B-48C4-8EE3-0541465EEACD%7C%7Crefdgdfgwe324234%7C%7CAF8F7A67-CDD0-4AD3-96C4-D447E970D0F8?X-Atmosphere-tracking-id=0&X-Atmosphere-Framework=2.3.1-javascript&X-Atmosphere-Transport=websocket&Content-Type=application/json;%20charset=UTF-8&X-atmo-protocol=true' failed: Error during WebSocket handshake: Unexpected response code: 302
atmosphere.js:3252 Sat Jan 30 2016 22:22:43 GMT+0100 (CET) Atmosphere: websocket.onerror
atmosphere.js:3252 Sat Jan 30 2016 22:22:43 GMT+0100 (CET) Atmosphere: websocket.onclose
atmosphere.js:3252 Websocket closed, reason: Connection was closed abnormally (that is, with no close frame being sent). - wasClean: false
atmosphere.js:3252 Sat Jan 30 2016 22:22:43 GMT+0100 (CET) Atmosphere: Firing onClose (closed case)
ConsoleLogger.java:32 AtmosphereListener: onClose
atmosphere.js:3252 Sat Jan 30 2016 22:22:43 GMT+0100 (CET) Atmosphere: Request already closed, not firing onClose (closed case)
atmosphere.js:3252 Websocket failed on first connection attempt. Downgrading to long-polling and resending
ConsoleLogger.java:32 AtmosphereListener: onTransportFailure: Websocket failed on first connection attempt. Downgrading to long-polling and resending
ConsoleLogger.java:32 AtmosphereListener: onTransportFailure: Websocket failed on first connection attempt. Downgrading to long-polling and resendingmhi_g$ @ ConsoleLogger.java:32Hgi_g$ @ SimpleConsoleLogHandler.java:36cgi_g$ @ Logger.java:262bgi_g$ @ Logger.java:250ugi_g$ @ Logger.java:178tgi_g$ @ Logger.java:162Agi_g$ @ Logger.java:129pNi_g$ @ AtmosphereListener.java:114(anonymous function) @ AtmosphereRequestConfig.java:389shc_g$ @ Impl.java:239vhc_g$ @ Impl.java:291(anonymous function) @ Impl.java:77_reconnectWithFallbackTransport @ atmosphere.js:1729_websocket.onclose @ atmosphere.js:1534
atmosphere.js:3252 Sat Jan 30 2016 22:22:43 GMT+0100 (CET) Atmosphere: ajaxRequest.onreadystatechange, new state: 2
2atmosphere.js:3252 Sat Jan 30 2016 22:22:43 GMT+0100 (CET) Atmosphere: ajaxRequest.onreadystatechange, new state: 3
atmosphere.js:2117 XHR finished loading: GET "http://www.example.com:8080/socket/widget/2418C3F0-9A9B-48C4-8…plication%2Fjson%3B%20charset%3DUTF-8&X-atmo-protocol=true&_=1454188963647"._executeRequest @ atmosphere.js:2117_execute @ atmosphere.js:644_reconnectWithFallbackTransport @ atmosphere.js:1745_websocket.onclose @ atmosphere.js:1534
atmosphere.js:3252 Sat Jan 30 2016 22:22:43 GMT+0100 (CET) Atmosphere: ajaxRequest.onreadystatechange, new state: 4
atmosphere.js:3252 Sat Jan 30 2016 22:22:43 GMT+0100 (CET) Atmosphere: ajaxRequest.onreadystatechange, new state: 2
atmosphere.js:3252 Sat Jan 30 2016 22:22:43 GMT+0100 (CET) Atmosphere: Firing onOpen

日志说:

第一次连接尝试时 Websocket 失败。降级为长轮询并重新发送

如何在服务器重启时强制 Atmosphere.js 使用首选传输 (Websockets) 而不是备用传输 (Long Polling)?

【问题讨论】:

【参考方案1】:

如何在服务器重新启动时强制 Atmosphere.js 使用首选传输 (Websockets) 而不是回退传输 (Long Polling)?

Atmosphere 客户端自动尝试使用fallbackTransport 重新连接。这是默认行为。

要强制它使用首选传输重新连接,您可能必须更改默认行为。

可以通过在大气.js see here 中注释掉这一行来改变这一点。

这将确保在重新连接时始终使用首选的 web-socket 传输,并且不会使用fallbackTransport

_websocket.onclose = function(webSocketOpened) 
//...
if (_abortingConnection) 
    atmosphere.util.log(_request.logLevel, ["Websocket closed normally"]);
/** remove if you never want to use fallback transport
 else if (!webSocketOpened) 
    _reconnectWithFallbackTransport("Websocket failed on first connection attempt. Downgrading to " + _request.fallbackTransport + " and resending");
*/
 else if (_request.reconnect && _response.transport === 'websocket' ) 
    _clearState();
    if (_requestCount++ < _request.maxReconnectOnClose) 
        _open('re-connecting', _request.transport, _request);
        if (_request.reconnectInterval > 0) 
            _request.reconnectId = setTimeout(function () 
                _response.responseBody = "";
                _response.messages = [];
                _executeWebSocket(true);
            , _request.reconnectInterval);
         else 
            _response.responseBody = "";
            _response.messages = [];
            _executeWebSocket(true);
        
    
 else 
        atmosphere.util.log(_request.logLevel, ["Websocket reconnect maximum try reached " + _requestCount]);
        if (_canLog('warn')) 
            atmosphere.util.warn("Websocket error, reason: " + message.reason);
        
        _onError(0, "maxReconnectOnClose reached");
    

另一种方法是使用onReconnect 回调动态切换回clientRequest.request 参数。

为什么?

因为当连接关闭并调用onTransportFailure 时。 Atmosphere 将传输更改为 fallbackTransport 并且最终可能以 = 'none' 结束(如果它设置为 websocket)。

假设您的请求包括以下配置:

  request.reconnectOnServerError= true,
  request.executeCallbackBeforeReconnect= true; 

您可以将此添加到您的 onReconnect 回调中:

   clientRequest.request.transport = 'websocket'; // force preferred transport on reconnect
   //clientRequest.request.fallbackTransport = 'websocket'; // optional

问题是,如果您将回退设置为websocket,它只会尝试重新连接一次,就好像您将其留空一样,如果您使用了url(以ws:// 开头,它仍将使用web-socket 协议或wss://) 而不是webSocketUrl

request.url = 'ws://example.com/ws'; 

【讨论】:

这有什么帮助? 能否再写一点解释。 嗯,它并没有真正的帮助。您应该记住,对于仅提供长轮询的客户端,它应该仍然有效。如果它通过长轮询连接,它应该检查 Websockets 是否可用并尽可能升级。 任何合适的解决方案?

以上是关于重新连接到服务器时如何强制 Atmosphere.js 使用首选传输?的主要内容,如果未能解决你的问题,请参考以下文章

如何在Mac上强制重新连接到VOO_HOMESPOT

GCM CCS 上游消息是不是强制重新连接到 GCM 网络?

C#如何强制等待连接到 WCF 服务

将 iOS 应用重新连接到配对的蓝牙设备?

如何强制 Django 使用服务名称连接到 Oracle

iOS:客户端如何重新连接到 xmpp 服务器