前后端分离项目使用WebSocket,报错 The remote party closed the WebSocket connection without completing the close handshake. 怎么解决,或者给一个完整的.net core案例
时间: 2024-02-16 09:03:29 浏览: 429
同样的错误在 .NET Core 中的解决方法也是类似的。下面是一个基于 .NET Core 的 WebSocket 示例代码,可能对你有帮助:
前端代码(使用 JavaScript):
```javascript
var socket = new WebSocket('ws://localhost:5000/ws');
socket.onopen = function() {
console.log('WebSocket connected');
}
socket.onmessage = function(event) {
console.log('Received message: ' + event.data);
}
socket.onclose = function(event) {
console.log('WebSocket closed with code: ' + event.code + ', reason: ' + event.reason);
}
socket.onerror = function(error) {
console.error('WebSocket error: ' + error);
}
```
后端代码(使用 .NET Core):
```csharp
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using System.Net.WebSockets;
using System.Threading;
using System.Threading.Tasks;
namespace WebSocketExample
{
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddWebSocketManager();
}
public void Configure(IApplicationBuilder app)
{
app.UseWebSockets();
app.Map("/ws", ws =>
{
ws.UseMiddleware<WebSocketManagerMiddleware>();
});
app.Run(async context =>
{
await context.Response.WriteAsync("Hello World!");
});
}
}
public class WebSocketManagerMiddleware
{
private readonly RequestDelegate _next;
private readonly WebSocketHandler _webSocketHandler;
public WebSocketManagerMiddleware(RequestDelegate next, WebSocketHandler webSocketHandler)
{
_next = next;
_webSocketHandler = webSocketHandler;
}
public async Task InvokeAsync(HttpContext context)
{
if (!context.WebSockets.IsWebSocketRequest)
{
await _next(context);
return;
}
var webSocket = await context.WebSockets.AcceptWebSocketAsync();
await _webSocketHandler.OnConnected(webSocket);
await Receive(webSocket, async (result, buffer) =>
{
if (result.MessageType == WebSocketMessageType.Text)
{
await _webSocketHandler.ReceiveAsync(webSocket, result, buffer);
return;
}
await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
await _webSocketHandler.OnDisconnected(webSocket);
});
}
private async Task Receive(WebSocket webSocket, WebSocketReceiveAsyncCallback callback)
{
var buffer = new byte[1024 * 4];
while (webSocket.State == WebSocketState.Open)
{
var result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
await callback(result, buffer);
}
}
}
public class WebSocketHandler
{
public virtual Task OnConnected(WebSocket webSocket)
{
return Task.CompletedTask;
}
public virtual Task OnDisconnected(WebSocket webSocket)
{
return Task.CompletedTask;
}
public virtual async Task ReceiveAsync(WebSocket webSocket, WebSocketReceiveResult result, byte[] buffer)
{
var message = System.Text.Encoding.UTF8.GetString(buffer, 0, result.Count);
await SendMessageAsync(webSocket, $"Hello, {message}!");
}
public async Task SendMessageAsync(WebSocket webSocket, string message)
{
var buffer = System.Text.Encoding.UTF8.GetBytes(message);
await webSocket.SendAsync(new ArraySegment<byte>(buffer, 0, buffer.Length), WebSocketMessageType.Text, true, CancellationToken.None);
}
}
public class WebSocketManager : WebSocketHandler
{
private readonly WebSocketConnectionManager _connectionManager;
public WebSocketManager(WebSocketConnectionManager connectionManager)
{
_connectionManager = connectionManager;
}
public override Task OnConnected(WebSocket webSocket)
{
return _connectionManager.AddWebSocketAsync(webSocket);
}
public override Task OnDisconnected(WebSocket webSocket)
{
return _connectionManager.RemoveWebSocketAsync(_connectionManager.GetId(webSocket));
}
}
public static class WebSocketExtensions
{
public static IServiceCollection AddWebSocketManager(this IServiceCollection services)
{
services.AddSingleton<WebSocketConnectionManager>();
services.AddSingleton<WebSocketManager>();
return services;
}
}
public class WebSocketConnectionManager
{
private readonly ConcurrentDictionary<string, WebSocket> _webSockets = new ConcurrentDictionary<string, WebSocket>();
public WebSocket GetWebSocketById(string id)
{
_webSockets.TryGetValue(id, out WebSocket webSocket);
return webSocket;
}
public ConcurrentDictionary<string, WebSocket> GetAll()
{
return _webSockets;
}
public string GetId(WebSocket webSocket)
{
return _webSockets.FirstOrDefault(x => x.Value == webSocket).Key;
}
public async Task AddWebSocketAsync(WebSocket webSocket)
{
_webSockets.TryAdd(Guid.NewGuid().ToString(), webSocket);
}
public async Task RemoveWebSocketAsync(string id)
{
_webSockets.TryRemove(id, out WebSocket webSocket);
await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "WebSocket closed", CancellationToken.None);
}
}
}
```
这个示例代码同样实现了一个简单的 WebSocket 服务,前端代码连接到 ws://localhost:5000/ws,后端代码使用 .NET Core 实现了一个 WebSocketManagerMiddleware 中间件来处理 WebSocket 连接。如果连接关闭时未完成关闭握手,会输出类似如下的错误信息:
```
System.Net.WebSockets.WebSocketException (0x80004005): The remote party closed the WebSocket connection without completing the close handshake.
at System.Net.WebSockets.ManagedWebSocket.ThrowIfEOFUnexpected(Boolean throwOnPrematureClosure)
at System.Net.WebSockets.ManagedWebSocket.<SendAsyncPrivate>d__60.MoveNext()
```
希望对你有帮助!
阅读全文