我正在用 Microsoft.NETCore.App 1.1.0 编写一个简单的websocket服务器。 我的程序基于this教程(教程代码:github)。到目前为止一切正常:我可以使用一个小程序连接到我的服务器。服务器响应我的请求。但是在这个响应之后,套接字被关闭了。
这是我的 SocketHandler.cs
的代码public class SocketHandler
{
public const int BufferSize = 4096;
private WebSocket _socket;
SocketHandler(WebSocket socket)
{
_socket = socket;
}
async Task EchoLoop()
{
var requestBuffer = new ArraySegment<byte>(new byte[BufferSize]);
var request = await _socket.ReceiveAsync(requestBuffer, CancellationToken.None);
var requestText = Encoding.UTF8.GetString(requestBuffer.Array,
requestBuffer.Offset, requestBuffer.Count);
var responseBytes = Encoding.UTF8.GetBytes(requestText);
var responseBuffer = new ArraySegment<byte>(responseBytes);
await _socket.SendAsync(responseBuffer, WebSocketMessageType.Text, true, CancellationToken.None);
}
static async Task Acceptor(HttpContext httpContext, Func<Task> next)
{
if (!httpContext.WebSockets.IsWebSocketRequest) return;
var socket = await httpContext.WebSockets.AcceptWebSocketAsync();
if (socket != null && socket.State == WebSocketState.Open)
{
var h = new SocketHandler(socket);
await h.EchoLoop();
}
else
{
await next();
}
}
public static void Map(IApplicationBuilder app)
{
app.UseWebSockets();
app.Use(Acceptor);
}
}
除了一件事之外,这与教程中的代码大致相同:我在发送消息后不关闭客户端中的套接字。不幸的是,在收到服务器回送后,我收到了&#39; onclose&#39; 事件。
我想知道如何在服务器上监听套接字事件,例如&#39; onopen&#39; ,&#39; onmassage&#39; 等我在WebSocketHandler看过。注册此类处理程序的方法已在NetCore中消失。
方法 AcceptWebSocketAsync()似乎总是创建一个新套接字。如果客户已经握手怎么办?我是否存储了这个已建立的连接并对其事件作出反应?
我想在服务器端列表中保存所有套接字连接并管理它们(广播消息,超时后关闭套接字等)。我是否必须使用HTTP会话来识别客户端并将其映射到列表中的打开套接字?我发现这个很好tutorial用于实现会话,但我不知道我是否采用了正确的方法。
套接字连接本身是否有我可以使用的ID?或者如何确定连接?
谢谢:)
[UPDATE]
我找到了一个解决方案来保持套接字打开。我在接受器任务中添加了一个while循环:
static async Task Acceptor(HttpContext httpContext, Func<Task> next)
{
if (!httpContext.WebSockets.IsWebSocketRequest) return;
var socket = await httpContext.WebSockets.AcceptWebSocketAsync();
if (socket != null)
{
var h = new SocketHandler(socket);
while (socket.State == WebSocketState.Open)
{
await h.EchoLoop();
}
}
await next();
}
在我看来,如果套接字对象失去其范围(并被gc删除),套接字将被关闭。我不知道这个假设是否正确。我不知道这个解决方案在CPU性能方面是否是一个好主意,因为我在while循环中等待套接字。 有什么想法吗?