WebSocket服务搭建

1、在NuGet包管理工具安装websocket包

 2、添加自定义中间件

app.UseWebSockets();
app.UseMiddleware<CustomWebSocketMiddleware>();

3、编写websocket中间件

private readonly RequestDelegate _next;
private ILogger<CustomWebSocketMiddleware> _Logger;
public List<WebSocketConnect> _connections = new List<WebSocketConnect>();
public CustomWebSocketMiddleware(RequestDelegate next, ILogger<CustomWebSocketMiddleware> logger)
{
_next = next;
_Logger = logger;
}

public async Task InvokeAsync(HttpContext context)
{
if (!context.WebSockets.IsWebSocketRequest)
{
await _next(context); // 如果不是WebSocket请求,则继续处理管道中的下一个中间件
return;
}
WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync();

// 启动WebSocket连接处理任务
await ProcessWebSocketAsync(context, webSocket);
}

private async Task ProcessWebSocketAsync(HttpContext context, WebSocket webSocket)
{
var buffer = new byte[1024 * 4]; // 4KB buffer
WebSocketReceiveResult result;
var ipProt = context.Request.Host.Value.Split(":");
WebSocketConnect connect = new WebSocketConnect
{
Socket = webSocket,
path = context.Request.Path.Value,
ip = ipProt[0],
port = ipProt[1]
};
_Logger.LogInformation($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}写入wobsocket连接,{ipProt[0]} {ipProt[1]}{ context.Request.Path.Value}");
//判断连接池是否存在该链接
if (!_connections.Any(connection => connection.path == context.Request.Path.Value && connection.Socket.State== WebSocketState.Open))
{
for (var i=0;i<_connections.Count;i++)
{
if (_connections[i].path==context.Request.Path && (_connections[i].Socket.State==WebSocketState.Closed || _connections[i].Socket.State == WebSocketState.Aborted))
{
_connections.Remove(_connections[i]);
}
}
_connections.Add(connect);
}
try
{
result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
while (!result.CloseStatus.HasValue)
{
if (result.MessageType == WebSocketMessageType.Text)
{
string receivedMessage = Encoding.UTF8.GetString(buffer, 0, result.Count);
Console.WriteLine($"Received: {receivedMessage}");

// 发送消息回显
//string echoMessage = $"Echo: {receivedMessage}";
await ProcessReceive(receivedMessage, webSocket, context);
result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
}
}
await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
}
catch (Exception ex)
{
_Logger.LogError(ex.Message);
if (webSocket.State == WebSocketState.Open)
{
_connections.Remove(connect);
await webSocket.CloseAsync(WebSocketCloseStatus.InternalServerError, "连接异常", CancellationToken.None);
}
}
}

private async Task ProcessReceive(string message, WebSocket webSocket, HttpContext context)
{

//处理消息

}


4、在前端调用websocket服务

const ws = ref(null)
const reconnection = () => {
  ws.value = new WebSocket(env.socket.baseUrl)
  ws.value.addEventListener('open', () => {
    socketState.value = '连接成功'
    console.log('连接成功')
  })
  ws.value.addEventListener('message', (event) => {
    
  })
  ws.value.addEventListener('close', (e) => {
    socketState.value = '连接已关闭'
    console.log('WebSocket连接已关闭')
  })
  ws.value.addEventListener('error', (error) => {
    socketState.value = '连接错误,已断开连接'
    console.error('WebSocket发生错误:', error)
  })
}

 发送消息

 ws.value.send(JSON.stringify(data))
 

 

posted @ 2024-05-27 16:24  绯颜旧雨  阅读(26)  评论(0编辑  收藏  举报