WebSocket小白,求助大佬,我想做一个跟服务器长连接的登录。
比如第一个用户登录了这个账号就把他记录在字典表里,如果有第二个人也登录了这个账号就给第一个账号发消息,说账号已在其他地方登录,然后关闭第一个人的连接,再跟第二个人连接。userId是客户端传过去的。
运行到 HandleWebSocket 里的
WebSocketReceiveResult result = await socket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None); 这句话就会一直等待消息,可是如果不执行这句话,发送消息的时候就会报错:远程参与方在未完成关闭握手的情况下关闭了WebSocket连接。 求助大佬,帮帮小白
下面贴代码
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Concurrent;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace CakePrintWeb2.WebSocketTest;
public class WebSocketMiddleware
{
private readonly RequestDelegate _next;
private readonly ConcurrentDictionary<string, WebSocket> _sockets;
public WebSocketMiddleware(RequestDelegate next)
{
_next = next;
_sockets = new ConcurrentDictionary<string, WebSocket>();
}
public async Task Invoke(HttpContext context)
{
if (context.Request.Path == "/ws")
{
if (context.WebSockets.IsWebSocketRequest)
{
WebSocket socket = await context.WebSockets.AcceptWebSocketAsync();
string userId = context.Request.Query["userId"];
_sockets.AddOrUpdate(userId, socket, (key, oldSocket) => socket);
await HandleWebSocket(socket, userId);
}
else
{
context.Response.StatusCode = 400;
}
}
else
{
await _next(context);
}
}
private async Task HandleWebSocket(WebSocket socket, string userId)
{
byte[] buffer = new byte[1024 * 4];
WebSocketReceiveResult result = await socket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
while (!result.CloseStatus.HasValue)
{
// Handle received message
result = await socket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
}
await SendToUser(_sockets[userId], "Your account has been logged in from another location. This connection will be closed.");
_sockets.TryRemove(userId, out _);
await socket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
}
private async Task SendToUser(WebSocket socket, string message)
{
var buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(message));
await socket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
}
}