63 lines
1.8 KiB
C#
63 lines
1.8 KiB
C#
using System.Net.WebSockets;
|
|
using MyApp.WebSockets;
|
|
|
|
namespace MyApp.WebSockets;
|
|
|
|
public class WebSocketMiddleware
|
|
{
|
|
private readonly RequestDelegate _next;
|
|
private readonly WebSocketManager _manager;
|
|
|
|
public WebSocketMiddleware(RequestDelegate next, WebSocketManager manager)
|
|
{
|
|
_next = next;
|
|
_manager = manager;
|
|
}
|
|
|
|
public async Task InvokeAsync(HttpContext context)
|
|
{
|
|
if (context.Request.Path == "/ws")
|
|
{
|
|
if (!context.WebSockets.IsWebSocketRequest)
|
|
{
|
|
context.Response.StatusCode = StatusCodes.Status400BadRequest;
|
|
return;
|
|
}
|
|
|
|
// Let the client pass a stable id: ws://host/ws?clientId=abc123
|
|
var clientId = context.Request.Query["clientId"].ToString();
|
|
if (string.IsNullOrWhiteSpace(clientId))
|
|
{
|
|
clientId = Guid.NewGuid().ToString("N");
|
|
}
|
|
|
|
using var socket = await context.WebSockets.AcceptWebSocketAsync();
|
|
_manager.AddSocket(clientId, socket);
|
|
|
|
await ReceiveLoop(clientId, socket);
|
|
_manager.RemoveSocket(clientId);
|
|
return;
|
|
}
|
|
|
|
await _next(context);
|
|
}
|
|
|
|
private static async Task ReceiveLoop(string id, WebSocket socket)
|
|
{
|
|
var buffer = new byte[4 * 1024];
|
|
|
|
while (socket.State == WebSocketState.Open)
|
|
{
|
|
var result = await socket.ReceiveAsync(buffer, CancellationToken.None);
|
|
|
|
if (result.MessageType == WebSocketMessageType.Close)
|
|
{
|
|
await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closing", CancellationToken.None);
|
|
break;
|
|
}
|
|
|
|
// (Optional) handle incoming messages here if you need two-way comms.
|
|
}
|
|
}
|
|
}
|