语境:
我们在 ASP.NET Core 2 MVC 应用程序中使用 Websockets。这是我们的 Startup.cs 类中的代码:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
[...]
app.Use(async (context, next) =>
{
if (context.WebSockets.IsWebSocketRequest)
{
if(context.Request.Path == "/ws")
{
WebSocket lWebSocket = await context.WebSockets.AcceptWebSocketAsync();
// a custom class that handles the websocket request → perhaps replace by an action controller.
var lHandleWebSocket = new HandleWebSocket();
await lHandleWebSocket.HandleConnection(context, lWebSocket);
}
}
}
}
数据传输将由“HandleConnection”类处理:
public async Task HandleConnection(HttpContext context, WebSocket pWebSocket)
{
var lBuffer = new byte[1024 * 4];
WebSocketReceiveResult lWebSocketReceiveResult = null;
string lTmpString = string.Empty;
// get next values
lWebSocketReceiveResult = await pWebSocket.ReceiveAsync(new ArraySegment(lBuffer), CancellationToken.None);
// Doing something here...
// close connection
await pWebSocket.CloseAsync(WebSocketCloseStatus.InternalServerError, "TestError", CancellationToken.None);
}
这是一个关于使用过的 JavaScript 的小片段:
self.WebSocketChat = new WebSocket("ws://" + window.location.host + "/ws");
self.WebSocketChat.onclose = function (data) { console.log(data); };
self.WebSocketChat.onerror = function (data) { console.log(data); };
描述:客户端与服务器连接。当客户端将第一条消息发送到服务器时,服务器将关闭连接。在客户端中,'onclose'-event 按预期触发并将以下信息输出到控制台:
Console: CloseEvent {isTrusted: true, wasClean: true, code: 1011, reason: "TestError", type: "close", …}
一切都按预期工作。
问题:
现在我们想在 server-side 上发生异常时关闭 websocket 连接。我们希望将异常的消息和 callstack 传递给结束帧。
在 Startup.cs-File 中捕获异常:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
[...]
app.Use(async (context, next) =>
{
if (context.WebSockets.IsWebSocketRequest)
{
if(context.Request.Path == "/ws")
{
WebSocket lWebSocket = await context.WebSockets.AcceptWebSocketAsync();
// a custom class that handles the websocket request → perhaps replace by an action controller.
var lHandleWebSocket = new HandleWebSocket();
try
{
await lHandleWebSocket.HandleConnection(context, lWebSocket);
}
catch (Exception e)
{
// close connection
await lWebSocket.CloseAsync(WebSocketCloseStatus.InternalServerError, e.ToString(), CancellationToken.None);
throw;
}
}
}
}
}
抛出异常:
public async Task HandleConnection(HttpContext context, WebSocket pWebSocket)
{
var lBuffer = new byte[1024 * 4];
WebSocketReceiveResult lWebSocketReceiveResult = null;
string lTmpString = string.Empty;
// get next values
lWebSocketReceiveResult = await pWebSocket.ReceiveAsync(new ArraySegment(lBuffer), CancellationToken.None);
// throw an exception
throw new TestException("TestException");
}
当我们现在向服务器发送消息时,将抛出 TestException 并按预期捕获:
但是在 client-side 上,'onclose'-Event 并没有开火。
self.WebSocketChat.onclose = function (data) { console.log(data); }; // nothing happens
'.onerror'事件也不会触发。
题:
如何在发生异常时关闭 Websocket 连接并将异常消息传递给客户端?