呼叫 Clients.Others.SendAsync 断开收件人

Calling Clients.Others.SendAsync disconnects recipient

为了测试我的应用程序,我在浏览器的本地主机上打开了多个到信号器集线器 运行 的连接。他们连接良好,直到一个客户端调用 Host 函数,此时其他客户端抛出错误:

[2020-04-23T18:17:18.374Z] Debug: HubConnection connected successfully. Utils.ts:178 [2020-04-23T18:17:18.511Z] Debug: HttpConnection.stopConnection(Error: WebSocket closed with status code: 1011 ().) called while in state Connected.

Utils.ts:168 [2020-04-23T18:17:18.511Z] Error: Connection disconnected with error 'Error: WebSocket closed with status code: 1011 ().'.

Utils.ts:178 [2020-04-23T18:17:18.512Z] Debug: HubConnection.connectionClosed(Error: WebSocket closed with status code: 1011 ().) called while in state Connected.

这是服务端的功能

        public async Task Host(string lobbyId)
        {
            //generate _lobbies here...
            await Clients.Others.SendAsync("ReceiveLobbies", 
                new { lobbies = new Lobby[] { _lobbies } })
        }

客户端函数 "ReceiveLobbies" 未被调用,因为连接已关闭。我已经做了一个快速测试,知道我可以在本地主机上有多个客户端,为什么会这样?

调试 signalr 应用程序后,我意识到我遇到了 json 序列化错误,因为大厅变量的深度超出了限制,现在显而易见的原因是我的 Lobby 对象包含一个 Player 对象列表,每个对象都有他们自己的大厅 属性,因此在序列化期间无限递归

my Lobby object contains a list of Player objects that each have their own Lobby property, ergo an infinite recursion during serialization

您可以尝试安装 Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson NuGet 包切换到 Newtonsoft.Json,然后您可以通过设置 ReferenceLoopHandling 设置使其忽略循环引用而不是抛出异常,如下所示。

services.AddSignalR().AddNewtonsoftJsonProtocol(opt=> {
    opt.PayloadSerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
});