尝试轮询现有连接时,SignalR Send方法未触发

时间:2018-01-23 21:09:04

标签: c# jquery asp.net signalr signalr-hub

我正在使用最新版本的SignalR和jQuery,并在用户断开连接的情况下获得一些奇怪的行为,但仍然在我的“UserQueue”中挂起,尽管已经断开连接。

我认为这可能与页面刷新似乎几乎同时触发OnDisconnectedOnConnected事件有关。当我在其中一个方法中设置断点并逐步执行时,我的指针在每个步骤(F10)之间来回反弹。

我想对每个OnConnected事件进行检查,以找出实际连接到我的应用的用户。我想从OnConnected事件中的C#代码中触发JS事件,然后允许客户端/前端发回用户确认信息:

public override Task OnConnected()
{
    // Check for other users:
    Clients.All.checkForOtherUsers();

    // Do stuff with my user queue
    var curmodelId = GetModelId(Context);
    var curUserConnection = GetCurrentUser(Context);
    // First create the ledger is missing, setting the modelId as the first key
    if (_ledger == null)
    {
        _ledger = new ConnectionLedger(curmodelId, curUserConnection);
    }
    else
    {
        // key not found, create new connection pool this model
        if (!_ledger.PoolIds.Contains(curmodelId))
        {
            _ledger.AddConnectionPool(curmodelId, curUserConnection);
        }
        else
        {
            var curModelPool = _ledger.ConnectionPools.First(x => x.Id == curmodelId);
            curModelPool.UserQueue.Enqueue(curUserConnection);
        }
    }

    return base.OnConnected();
}   

现在在客户端JS中,如果我有这段代码:

modelHub.client.checkForOtherUsers = function () {
    // I can see logging here if I add console.log("checking for other users...")
    modelHub.server.send();
}

...我期待我的C#Send方法接收上下文(如果用户实际出现在客户端以供JS执行)并更新我的UserQueue

public void Send()
{
    var curmodelId = GetModelId(Context);
    var curModelPool = _ledger.ConnectionPools.First(x => x.Id == curmodelId);
    var curUserConnection = GetCurrentUser(Context);
    curModelPool.UserQueue.Enqueue(curUserConnection);
}

...但我的Send方法永远不会被解雇,即使我直接从JS控制台$.connection.modelingHub.server.send()启动它。

为什么Send方法不会触发?有没有关于SignalR库的事件顺序/异步性质导致这种情况?

对整体设计的评论也是受欢迎的(因为我怀疑它可能是愚蠢的),但请注意,由于我的自定义身份验证配置,我无法访问Context.UserClients.User

1 个答案:

答案 0 :(得分:1)

似乎是下面两个原因。

服务器侧
不能在Clients.All.checkForOtherUsers();内拨打OnConnected() 我建议在连接后调用它。

请参阅SignalR - Send message OnConnected

<强>客户端
在调用start方法之前可能需要注册modelHub.client.checkForOtherUsers = function () {

  

通常在调用start方法之前注册事件处理程序   建立连接。如果你想注册一些活动   建立连接后的处理程序,你可以这样做,但你   必须在调用之前注册至少一个事件处理程序   开始方法。
- How to establish a connection