【问题标题】:SignalR invoke method doesn't work on throttled connectionsSignalR 调用方法不适用于受限制的连接
【发布时间】:2022-01-31 11:26:10
【问题描述】:

我有一个带有 SignalR 的 .net 核心后端和一个反应前端。我有一个使用 ConcurrentDictionary 设置的基本集线器来管理连接 ID:

namespace backend.Hubs
{
    public class OrderHub : Hub, IOrderHub
    {
        private readonly IHubContext<OrderHub> hubContext;
        public static ConcurrentDictionary<string, List<string>> ConnectedUsers = new ConcurrentDictionary<string, List<string>>();

        public OrderHub(IHubContext<OrderHub> hubContext)
        {
            this.hubContext = hubContext;
        }
        public async Task SendMessage(OrderResponseDto order, string id)
        {
            List<string> connectedUser = null;
            ConnectedUsers.TryGetValue(id, out connectedUser);
            await hubContext.Clients.Clients(connectedUser).SendAsync("neworder",order);
        }
        public void AddMapping(string id)
        {
            List<string> existingUserConnectionIds;
            ConnectedUsers.TryGetValue(id, out existingUserConnectionIds);
            if (existingUserConnectionIds == null)
            {
                existingUserConnectionIds = new List<string>();
            }
            existingUserConnectionIds.Add(Context.ConnectionId);
            ConnectedUsers.TryAdd(id, existingUserConnectionIds);
        }
        public override Task OnDisconnectedAsync(Exception e)
        {

            List<string> existingUserConnectionIds = null;
            foreach(var val in ConnectedUsers.Values)
            {
                if (val.Contains(Context.ConnectionId))
                {
                    existingUserConnectionIds = val;
                    break;
                }
            }
            if (existingUserConnectionIds != null)
            {
                existingUserConnectionIds.Remove(Context.ConnectionId);
            }
            var keys = ConnectedUsers.Where(en => en.Value.Count == 0).Select(k => k.Key);
            foreach(var key in keys)
            {
                List<string> garb = null;
                ConnectedUsers.TryRemove(key, out garb);
            }
            return base.OnDisconnectedAsync(e);
        }
    }

}

在前端,我建立连接并调用AddMapping 方法将客户端连接id 保存到并发字典中。当前端的开发者控制台中没有启用限制时,一切正常。但是,如果我将节流更改为慢速或快速 3g,我会遇到一个奇怪的问题。连接照常建立,我调用该方法。从 .net 核心中的调试中,我看到该方法是在后端调用的,但是该值没有保存在并发字典中,也没有返回任何内容。反应客户端认为连接丢失并重新连接。具体来说,我收到以下错误:

仅当我尝试在受限制的连接上从客户端调用集线器方法时才会发生此错误。在不受限制的连接上,它可以正常工作。

附加客户端代码:

const newConnection = new HubConnectionBuilder()
            .withUrl(env.realtimeBaseUrl+'orderhub', {
                // skipNegotiation: true,
                // transport: HttpTransportType.WebSockets
            })
            .withAutomaticReconnect()
            .build();
        newConnection.start().then(r => {
            fetchOrders()
            setConnectionStatus(connectingForFirstTime);
            newConnection.invoke("AddMapping",business.id.toString()).then(res=>{
                console.log(res)
                setConnection(newConnection);
                setConnectionStatus(connected)
            })
            newConnection.on("neworder",(order)=>{
               // data handling
            })
            newConnection.onreconnecting(()=>setConnectionStatus(reconnecting))
            newConnection.onreconnected(()=>{
                newConnection.invoke("AddMapping",business.id.toString()).then(res=>{
                    console.log(res)
                    setConnection(newConnection);
                    setConnectionStatus(connected)
                })
            });
            newConnection.onclose(()=>setConnection(null));
        }).catch(err => setConnectionStatus(off));

【问题讨论】:

    标签: c# reactjs .net-core websocket signalr


    【解决方案1】:

    我刚刚在我的一个网站上尝试过,似乎开发工具执行节流的方式会中断 websocket 连接,以至于无论是在 slow3g 还是 fast3g 模拟上,它似乎都无法双向工作。我可以在我原本可以工作的网站上重现您的错误。我怀疑是模拟器,而不是你的代码。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-08
    • 2017-05-09
    • 2021-05-22
    • 1970-01-01
    • 2018-10-26
    • 2019-10-03
    • 1970-01-01
    相关资源
    最近更新 更多