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) }) }
傳送訊息