语境:

我们在 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<byte>(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<byte>(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 连接并将异常消息传递给客户端?