如何处理关闭握手 C#
How to handle the close handshake c#
我使用 websockets 和 https 调用在 c# 中开发了一个猜谜游戏。每次用户创建要玩的控制台应用程序实例时,它都会与服务器连接。 (等待 webSocket.ConnectAsync(new Uri("ws://localhost:xxx"), CancellationToken.None);).
我有一个 websocketmiddlewear class 来接受 websocket 请求和一个管理器 class 来处理 websockets 请求。一切正常,除非用户退出主机游戏。例如,当我在控制台 (cmd) 中按“x”时,出现以下错误
The remote party closed the WebSocket connection without completing
the close handshake.
下一行
WebSocketReceiveResult result = await socket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
为什么代码没有处理错误,我该如何解决?
ConnectionManagerService.cs
public async Task Receive(WebSocket socket)
{
var buffer = new byte[1024 * 4];
while (socket.State == WebSocketState.Open)
{
WebSocketReceiveResult result = await socket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
if (result.MessageType == WebSocketMessageType.Text)
{
Console.WriteLine($"Receive->Text");
return;
}
else if (result.MessageType == WebSocketMessageType.Close)
{
string id = _sockets.FirstOrDefault(s => s.Value == socket).Key;
//Console.WriteLine($"Receive->Close on: " + id);
_sockets.TryRemove(id, out socket);
Console.WriteLine("Managed Connections: " + _sockets.Count.ToString());
await socket.CloseOutputAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
return;
}
}
}
WebsocketMiddleware.cs
}
public async Task Invoke(HttpContext context)
{
var isSocketRequest = context.WebSockets.IsWebSocketRequest;
if (isSocketRequest)
{
WebSocket socket = await context.WebSockets.AcceptWebSocketAsync();
_manager.AddSocket(socket);
await _manager.Receive(socket);
}
else
{
await _next(context);
}
}
发生这种情况是因为您只处理正常连接 disconnect.The 客户端可能会断开连接,并且您会在 read/write
操作过程中变大 ol
SocketIO Exception
.
考虑将您的 Socket
操作包装在 try-catch
中,并根据需要进行处理。
public async Task Receive(WebSocket socket)
{
var buffer = new byte[1024 * 4];
try{
while (true)
{
WebSocketReceiveResult result = await socket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
if (result.MessageType == WebSocketMessageType.Text)
{
Console.WriteLine($"Receive->Text");
return;
}
else if (result.MessageType == WebSocketMessageType.Close)
{
string id = _sockets.FirstOrDefault(s => s.Value == socket).Key;
//Console.WriteLine($"Receive->Close on: " + id);
_sockets.TryRemove(id, out socket);
Console.WriteLine("Managed Connections: " + _sockets.Count.ToString());
await socket.CloseOutputAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
return;
}
}
} catch(Exception ex){ //not so graceful disconnect
_sockets.TryRemove(id, out socket);
//deal with closed connection
//maybe reconnect ?
}
}
我使用 websockets 和 https 调用在 c# 中开发了一个猜谜游戏。每次用户创建要玩的控制台应用程序实例时,它都会与服务器连接。 (等待 webSocket.ConnectAsync(new Uri("ws://localhost:xxx"), CancellationToken.None);).
我有一个 websocketmiddlewear class 来接受 websocket 请求和一个管理器 class 来处理 websockets 请求。一切正常,除非用户退出主机游戏。例如,当我在控制台 (cmd) 中按“x”时,出现以下错误
The remote party closed the WebSocket connection without completing the close handshake.
下一行
WebSocketReceiveResult result = await socket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
为什么代码没有处理错误,我该如何解决?
ConnectionManagerService.cs
public async Task Receive(WebSocket socket)
{
var buffer = new byte[1024 * 4];
while (socket.State == WebSocketState.Open)
{
WebSocketReceiveResult result = await socket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
if (result.MessageType == WebSocketMessageType.Text)
{
Console.WriteLine($"Receive->Text");
return;
}
else if (result.MessageType == WebSocketMessageType.Close)
{
string id = _sockets.FirstOrDefault(s => s.Value == socket).Key;
//Console.WriteLine($"Receive->Close on: " + id);
_sockets.TryRemove(id, out socket);
Console.WriteLine("Managed Connections: " + _sockets.Count.ToString());
await socket.CloseOutputAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
return;
}
}
}
WebsocketMiddleware.cs
}
public async Task Invoke(HttpContext context)
{
var isSocketRequest = context.WebSockets.IsWebSocketRequest;
if (isSocketRequest)
{
WebSocket socket = await context.WebSockets.AcceptWebSocketAsync();
_manager.AddSocket(socket);
await _manager.Receive(socket);
}
else
{
await _next(context);
}
}
发生这种情况是因为您只处理正常连接 disconnect.The 客户端可能会断开连接,并且您会在 read/write
操作过程中变大 ol
SocketIO Exception
.
考虑将您的 Socket
操作包装在 try-catch
中,并根据需要进行处理。
public async Task Receive(WebSocket socket)
{
var buffer = new byte[1024 * 4];
try{
while (true)
{
WebSocketReceiveResult result = await socket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
if (result.MessageType == WebSocketMessageType.Text)
{
Console.WriteLine($"Receive->Text");
return;
}
else if (result.MessageType == WebSocketMessageType.Close)
{
string id = _sockets.FirstOrDefault(s => s.Value == socket).Key;
//Console.WriteLine($"Receive->Close on: " + id);
_sockets.TryRemove(id, out socket);
Console.WriteLine("Managed Connections: " + _sockets.Count.ToString());
await socket.CloseOutputAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
return;
}
}
} catch(Exception ex){ //not so graceful disconnect
_sockets.TryRemove(id, out socket);
//deal with closed connection
//maybe reconnect ?
}
}