如果无法建立 Websocket 连接,请执行其他操作

Posted

技术标签:

【中文标题】如果无法建立 Websocket 连接,请执行其他操作【英文标题】:If Websocket connection can't be established do something else 【发布时间】:2015-03-07 14:00:31 【问题描述】:

我目前遇到了一个问题,你们也许可以帮我解决..

我正在使用 websockets 连接到自定义服务器。现在,如果第一个服务器 IP 不可用,我想集成第二个服务器 IP。

如何检测到由于无法访问服务器而无法建立连接?例如,当我在脚本中输入错误的 ws://url 时,Chrome 会给我以下错误:

到“wss://1234/”的 WebSocket 连接失败:连接建立错误:net::ERR_NAME_NOT_RESOLVED

在 Firefox 中,情况完全不同。你们有什么方法可以用 javascript 捕获这个错误吗?

基本上当无法访问 ws:// url 时,我想用不同的 Server-IP 更改一个变量,然后用这个再次尝试...

感谢您的帮助!

【问题讨论】:

您可以随时退回到 ajax 长轮询方法。 嘿@3boll,谢谢!你能解释得更详细一点吗?我从未使用过 ajax 长轮询.. 谷歌研究对我也没有太大帮助.. Socket.IO (socket.io) 是一个项目,如果浏览器不支持 websockets,它会自动回退到长轮询,所以如果你需要的话,你可能想研究一下。跨度> 哦,这不是关于用户没有 websockets 的问题。我现在使用 websockets 连接到某个 url,ws://127.0.0.1,如果这个主机不会由于某种原因可用,出现相同的错误,就好像您将我们的 ws:// 那不存在一样。我需要捕获这种特定类型的错误,然后切换到尝试另一个 ws:// IP...基本上:如果 IP1 关闭,请尝试 IP2...它会触发“onClose”事件,目前为止是正确的..但如果有一种“服务器不可用”的方法会更好。我将 onClose 事件用于在重新连接时会发生冲突的其他内容。 是的,我意识到,并且正在输入一个(通用)答案,但上面的评论最终并没有太大帮助,所以我想我也会在这里加入。 【参考方案1】:

感谢@orbitbot,

我正在使用一个名为 jwebsocket (jwebsocket.org) 的框架。我的代码基本上是这样的:

	serverstate = "0";
	console.log(serverstate);

function logon() 
	
	
	if(serverstate == "0") 
		lURL = "wss://testurl-one:9797";
	 else if (serverstate == "1") 
		lURL = "wss://testurl-two:9797";
	
	
	
	var gUsername = "user";
	var lPassword = "pass";

	console.log( "Connecting to " + lURL + " and console.logging in as '" + gUsername + "'..." );
	
	var lRes = lWSC.logon( lURL, gUsername, lPassword, 

		// OnOpen callback
		OnOpen: function( aEvent ) 
			console.log( "jWebSocket connection established." );
		,
		
		// OnMessage callback
		OnMessage: function( aEvent, aToken ) 
			var lDate = "";
			if( aToken.date_val ) 
				lDate = jws.tools.ISO2Date( aToken.date_val );
			
			console.log( "jWebSocket '" + aToken.type + "' token received, full message: '" + aEvent.data + "' " + lDate + "" );
			console.log(aToken);
					
			
			
		,
		
		// OnClose callback
		OnClose: function( aEvent ) 
			console.log( "Disconnected from Server" );
			console.log("Using next server..");
			serverstate = "1";
			console.log(serverstate);
			console.log("Trying to connect to next server");
			logon();
		,
		
		// OnClose callback
		OnError: function( aEvent ) 
			console.log ("Some error appeared");
		
	
	);
		
	console.log( lWSC.resultToString( lRes ) );

到目前为止,这当然行得通。我的问题是我使用 websockets 打开连接,获取一些信息,然后再次关闭连接。

因为如果服务器连接关闭(在很多情况下我想这样做),这段代码总是会被触发。我不能那样使用它......

关于这个问题的任何其他想法?

【讨论】:

我假设您会在 OnCloseOnError 回调或两者中收到与上面的 try/catch 建议类似的错误事件,因此您需要发现问题出在哪一个通过检查aEvent 阻止。如果不是要检查的错误号,该事件可能有一个标准化的字符串(可能因浏览器而异)。根据您收到的错误消息,决定您是否需要退出或尝试其他网址。代码结构对于重试不同的 url 有点问题,因为你不应该直接将 lWSC.logon( 放在一个方法中并在 OnError/OnClose 中调用它。 是的.. 好提示!我试过这个,但不幸的是 aEvent 只是输出:CloseEvent reason: "", code: 1006, wasClean: false, path: NodeList[0], cancelBubble: false... .. 代码总是一样的,原因总是空的..无论是因为我想要关闭连接,还是因为服务器不可用..【参考方案2】:

似乎没有办法在实例化时发现问题,尽管神奇的 JavaScript 黑盒似乎知道问题发生在新的 WebSocket 上。

要检测此错误,请使用以下命令:

ws = new WebSocket(server);

ws.onerror = function (evt) 
    if (ws.readyState == 3) 
        //Connection closed.
    

【讨论】:

【参考方案3】:

我知道了.. 给所有感兴趣的人:

建立连接后,您会收到来自服务器的消息。因此,如果服务器不可用.. 将没有消息。所以我只是在“OnMessage”部分添加了一个变量..并在断开连接时检查是否收到了消息。如果不是,则服务器不存在.. 如果是,一切正常..

【讨论】:

【参考方案4】:

假设你的代码是这样的,

var host = 'ws://a.real.websocket.url';
var socket = new WebSocket(host);

...你只需要用 try/catch 块包围对 new WebSocket 的调用,就像这样

try 
  var socket = new WebSocket(host);
 catch (e) 
  // inspect e to understand why there was an error
  // and connect to another url if necessary

话虽如此,使用诸如 Socket.IO 或 SockJS (https://github.com/sockjs/sockjs-client) 之类的 websockets 库可能会更容易,然后将您的重新连接代码逻辑更改为库提供的任何内容。

【讨论】:

我很确定“异常”这个词不应该存在:语法错误 是的,这将是通常的指标 :) 已编辑删除。 对我不起作用(如果服务器关闭,则不会引发异常)。

以上是关于如果无法建立 Websocket 连接,请执行其他操作的主要内容,如果未能解决你的问题,请参考以下文章

无法建立 iPython 笔记本 Websocket 连接

python 如何建立socket长连接

使用 apache 建立安全 websocket 连接

无法建立 SSL 连接,请参阅内部异常

Spring 4.0 WebSocket 示例应用程序:无法建立 websocket 连接

为啥我的应用无法在 Heroku 上建立 websocket 连接?