WebSocket连接异常排查:客户端closed状态与服务端证书错误问题
解决websocket-sharp服务端启动异常及客户端连接Closed问题
问题现象
使用C#的websocket-sharp库搭建WebSocket服务时,客户端JavaScript显示连接状态为closed;服务端调用Start()方法时抛出System.InvalidOperationException异常,提示“无安全连接的服务器证书”。
问题原因
websocket-sharp的WebSocketServer构造函数在分开传入地址和端口两个参数时,默认会启用安全WebSocket连接(wss协议),此时要求服务端配置对应的SSL证书。如果未配置证书,启动服务就会触发上述异常,最终导致客户端连接失败。
解决方法
将构造函数的参数改为传入带ws://前缀的完整地址字符串(无需单独传入端口),明确指定使用非安全的WebSocket连接,异常即可消失:
WebSocketServer mWebSocketServer; try { // 传入完整ws协议地址,无需单独传端口 mWebSocketServer = new WebSocketServer("ws://192.168.5.73:443"); mWebSocketServer.AddWebSocketService<clsQuintexMsg>("/clsQuintexMsg"); mWebSocketServer.Start(); // 确保调用Start()启动服务 } catch (Exception ex) { FrmMain.UpdateTaskbar(ex.ToString()); }
原故障代码及异常信息
原C#服务端代码
WebSocketServer mWebSocketServer; try { // Creation of server, ipWebSocketAddr = "ws://192.168.5.73/posttest.html // mcintWebSocketPort = 443 mWebSocketServer = new WebSocketServer(ipWebSocketAddr, mcintWebSocketPort); mWebSocketServer.AddWebSocketService<clsQuintexMsg>("/clsQuintexMsg"); } catch (Exception ex) { FrmMain.UpdateTaskbar(ex.ToString()); }
原JavaScript客户端代码
try { webSocket = new WebSocket(cstrServerSocketIP); //Setup timeout timer to timeout if webSocket does not connect tmrCheckWebSocket = setInterval(function() { var strMsg = "Checking webSocket (" + cstrServerSocketIP + "), "; if (typeof webSocket == "object" && typeof webSocket.readyState == "number") { if (webSocket.readyState == WebSocket.CONNECTING) { strMsg += "connecting"; } else if (webSocket.readyState == WebSocket.OPEN) { strMsg += "open (connected)"; } else if (webSocket.readyState == WebSocket.CLOSING) { strMsg += "closing"; } else if (webSocket.readyState == WebSocket.CLOSED) { strMsg += "closed"; } } else { strMsg += "not a valid websocket!"; } DebugMsg(strMsg); }, cintCheckWebSocketInterval); webSocket.onclose = (event) => { var strReason = ""; if (typeof event == "object") { if (typeof event.code == "number") { strReason += "code[" + event.code + "]"; var strError = cobjWebSocketErrors[event.code]; if (typeof strError == "string") { strReason += ":" + strError; } } if (typeof event.reason == "string" && event.reason.length > 0) { if (strReason.length > 0) { strReason += ", "; } strReason += "reason:\"" + event.reason + "\""; } } DebugMsg("webSocket.onclose " + strReason); }; webSocket.onerror = (event) => { DebugMsg("webSocket.onerror" + ((typeof event == "object" && typeof event.data != "undefined") ? ":" + String(event.data) : "")); }; webSocket.onmessage = (event) => { DebugMsg("webSocket.onmessage"); if (event.data instanceof ArrayBuffer) { console.lob("Received ArrayBuffer"); console.lob(event.data); } webSocket.close(); }; webSocket.onopen = () => { DebugMsg("webSocket.onopen"); }; //Set-up timer to send requests for data updates InstallServiceTimer(cintServiceRequestInterval); } catch (e) { DebugMsg(e); }
服务端异常信息
System.InvalidOperationException HResult=0x80131509 Message=There is no server certificate for secure connection. Source=websocket-sharp StackTrace: at WebSocketSharp.Server.WebSocketServer.start() at WebSocketSharp.Server.WebSocketServer.Start() at CheetahCS.clsServer..ctor(String strRoot, String strDefault, Int32 intWWWPort, Int32 intWebSocketPort) in clsServer.cs:line 131 This exception was originally thrown at this call stack: WebSocketSharp.Server.WebSocketServer.start() WebSocketSharp.Server.WebSocketServer.Start() clsServer.clsServer(string, string, int, int) in clsServer.cs
内容的提问来源于stack exchange,提问作者SPlatten




