You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

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

火山引擎 最新活动