在Safari中关闭已连接WebSocket时提示‘未连接’错误的原因
问题分析与解决
问题原因
- 客户端时序问题:你的JavaScript代码在创建WebSocket实例后立刻调用
send和close,此时WebSocket连接可能尚未完全建立(WebSocket连接建立是异步过程),即便表面上readyState显示为OPEN,Safari的底层连接握手可能仍未完成,导致关闭时触发错误。 - 服务器异常未处理:当客户端提前断开连接时,服务器的
ReceiveAsync或CloseAsync可能抛出异常,未被捕获的异常会导致连接关闭流程异常,进而触发客户端的错误提示。
解决方案
1. 修正客户端代码,确保连接建立后再操作
将send和close放在onopen事件回调中,保证连接完全建立后再执行发送和关闭操作:
const ws = new WebSocket('ws://localhost:8080'); ws.onopen = () => { ws.send('abc'); ws.close(); };
2. 服务器代码添加异常处理,完善关闭流程
修改Echo方法,添加异常捕获逻辑,处理客户端提前断开的情况,确保连接关闭流程正常:
static async Task Echo(System.Net.WebSockets.WebSocket webSocket) { var buffer = new byte[1024 * 4]; WebSocketReceiveResult result; try { result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None); while (!result.CloseStatus.HasValue) { await webSocket.SendAsync(new ArraySegment<byte>(buffer, 0, result.Count), result.MessageType, result.EndOfMessage, CancellationToken.None); result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None); } await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None); } catch (Exception ex) { // 处理客户端提前断开等异常情况 if (webSocket.State == WebSocketState.Open) { await webSocket.CloseAsync(WebSocketCloseStatus.AbnormalClosure, "连接异常关闭", CancellationToken.None); } } }
3. 可选:配置WebSocket保持连接参数
在启用WebSocket中间件时添加KeepAliveInterval配置,优化连接稳定性:
app.UseWebSockets(new WebSocketOptions { KeepAliveInterval = TimeSpan.FromSeconds(30), });
内容的提问来源于stack exchange,提问作者Jason Graham
相关产品推荐
相关产品推荐

