重新连接到服务器时如何强制 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 使用首选传输?的主要内容,如果未能解决你的问题,请参考以下文章