private void Ws_OnClose(object sender, CloseEventArgs e) { WebSocket ws = (WebSocket)sender; if (_ws != ws) { return; } #region try { LastTryOn = DateTime.Now; CloseStatusCode closeStatus = CloseStatusCode.Undefined; if (Enum.IsDefined(typeof(CloseStatusCode), e.Code)) { closeStatus = (CloseStatusCode)e.Code; _closeCode = closeStatus.GetName(); } else { _closeCode = e.Code.ToString(); } Logger.InfoDebugLine($"Ws_OnClose {_closeCode} {e.Reason}"); switch (closeStatus) { case CloseStatusCode.Normal: _closeReason = e.Reason; if (e.Reason == WsMessage.ReGetServerAddress) { _closeReason = "服务器通知客户端重连"; // 3,收到服务器的WsMessage.ReGetServerAddress类型的消息时 NeedReWebSocket(); // 立即重连以防止在上一个连接关闭之前重连成功从而在界面上留下错误顺序的消息 NewWebSocket(); } else { // 正常关闭时,递增失败次数以增大重试延迟周期 IncreaseFailCount(); } break; case CloseStatusCode.Away: // 服务器ping不通时和服务器关闭进程时,递增失败次数以增大重试延迟周期 IncreaseFailCount(); _closeReason = "失去连接,请稍后重试"; // 可能是因为服务器节点不存在导致的失败,所以下一次进行重新获取服务器地址的全新连接 // 2,连不上服务器时 NeedReWebSocket(); break; case CloseStatusCode.ProtocolError: case CloseStatusCode.Undefined: // 协议错误导致连接关闭,递增失败次数以增大重试延迟周期 IncreaseFailCount(); // WebSocket协议并无定义状态码用于表达握手阶段身份验证失败的情况,阅读WebSocketSharp的源码发现验证不通过包含于ProtocolError中, // 姑且将ProtocolError视为用户名密码验证不通过,因为ProtocolError包含的其它失败情况在编程正确下不会发送。 _closeReason = "登录失败"; break; case CloseStatusCode.UnsupportedData: break; case CloseStatusCode.NoStatus: break; case CloseStatusCode.Abnormal: // 服务器或本机网络不可用时,递增失败次数以增大重试延迟周期 IncreaseFailCount(); _closeReason = "网络错误"; // 可能是因为服务器节点不存在导致的失败,所以下一次进行重新获取服务器地址的全新连接 // 2,连不上服务器时 NeedReWebSocket(); break; case CloseStatusCode.InvalidData: break; case CloseStatusCode.PolicyViolation: break; case CloseStatusCode.TooBig: break; case CloseStatusCode.MandatoryExtension: break; case CloseStatusCode.ServerError: break; case CloseStatusCode.TlsHandshakeFailure: break; default: break; } } catch { } NextTrySecondsDelayInit(); UpdateWsStateAsync($"{_closeCode} {_closeReason}", toOut: false); #endregion }
private void Ws_OnClose(object sender, CloseEventArgs e) { WebSocket ws = (WebSocket)sender; if (_ws != ws) { return; } #region try { LastTryOn = DateTime.Now; CloseStatusCode closeStatus = CloseStatusCode.Undefined; if (Enum.IsDefined(typeof(CloseStatusCode), e.Code)) { closeStatus = (CloseStatusCode)e.Code; _closeCode = closeStatus.GetName(); } else { _closeCode = e.Code.ToString(); Logger.InfoDebugLine($"意外的Ws关闭码:{_closeCode}"); } if (closeStatus == CloseStatusCode.ProtocolError || closeStatus == CloseStatusCode.Undefined) { // 协议错误导致连接关闭,递增失败次数以增大重试延迟周期 IncreaseFailCount(); // WebSocket协议并无定义状态码用于表达握手阶段身份验证失败的情况,阅读WebSocketSharp的源码发现验证不通过包含于ProtocolError中, // 姑且将ProtocolError视为用户名密码验证不通过,因为ProtocolError包含的其它失败情况在编程正确下不会发送。 _closeReason = "登录失败"; } else if (closeStatus == CloseStatusCode.Away) { // 服务器ping不通时和服务器关闭进程时,递增失败次数以增大重试延迟周期 IncreaseFailCount(); _closeReason = "失去连接,请稍后重试"; // 可能是因为服务器节点不存在导致的失败,所以下一次进行重新获取服务器地址的全新连接 // 2,连不上服务器时 NeedReWebSocket(); } else if (closeStatus == CloseStatusCode.Abnormal) { // 服务器或本机网络不可用时,递增失败次数以增大重试延迟周期 IncreaseFailCount(); _closeReason = "网络错误"; // 可能是因为服务器节点不存在导致的失败,所以下一次进行重新获取服务器地址的全新连接 // 2,连不上服务器时 NeedReWebSocket(); } else if (closeStatus == CloseStatusCode.Normal) { _closeReason = e.Reason; if (e.Reason == WsMessage.ReGetServerAddress) { _closeReason = "服务器通知客户端重连"; // 3,收到服务器的WsMessage.ReGetServerAddress类型的消息时 NeedReWebSocket(); // 立即重连以防止在上一个连接关闭之前重连成功从而在界面上留下错误顺序的消息 NewWebSocket(); } else { // 正常关闭时,递增失败次数以增大重试延迟周期 IncreaseFailCount(); } } } catch { } UpdateNextTrySecondsDelay(); UpdateWsStateAsync($"{_closeCode} {_closeReason}", toOut: false); #endregion }