WebsocketClient因服务端故障断开后如何安全重连?规避递归栈溢出
解决WebSocketClient断开后安全重连的方法
核心思路
不能在DisconnectionHappened事件处理方法内直接同步调用重连操作——这会因为重连失败再次触发该事件,形成无限递归导致栈溢出。正确的做法是异步延迟执行重连,并添加状态标记避免重复发起重连请求。
具体实现步骤
- 添加重连状态标记
定义一个布尔变量(比如isReconnecting),用来标记当前是否正在尝试重连,防止多个重连请求同时触发。 - 异步延迟执行重连逻辑
在DisconnectionHappened事件处理中,先检查状态标记,如果未在重连,则标记为重连中,通过异步延迟(如Task.Delay)再执行重连操作,重连完成后重置状态标记。
代码示例
private bool isReconnecting = false; private readonly WebSocketClient _client; public YourClientWrapper(WebSocketClient client) { _client = client; _client.DisconnectionHappened += OnDisconnectionHappened; } private async void OnDisconnectionHappened(object sender, DisconnectionEventArgs e) { // 排除主动关闭的情况,只处理异常断开 if (e.CloseStatus == WebSocketCloseStatus.NormalClosure) return; if (isReconnecting) return; isReconnecting = true; try { // 延迟5秒再重连,避免频繁请求压垮恢复中的服务端 await Task.Delay(5000); // 先确保客户端已停止 if (_client.IsStarted) _client.Stop(); // 尝试重连 await _client.StartOrReconnectAsync(); } catch (Exception ex) { // 记录重连失败日志 Console.WriteLine($"重连失败: {ex.Message}"); } finally { isReconnecting = false; } }
关键注意点
- 状态标记的线程安全:如果是多线程环境,建议用
Interlocked类操作isReconnecting变量,避免竞态条件。 - 延迟时间的设置:根据实际场景调整延迟时长,太短可能导致服务端恢复前频繁重试,太长则影响重连效率。
- 异常处理:重连过程中可能抛出异常,需添加日志记录或其他容错逻辑,避免程序崩溃。
内容的提问来源于stack exchange,提问作者da66en
相关产品推荐
相关产品推荐

