【问题标题】:SignalR - Send message OnConnectedSignalR - 发送消息 OnConnected
【发布时间】:2015-05-20 22:35:07
【问题描述】:

我今天一直在尝试 SignalR,它真的很简洁。基本上我想要实现的目标如下:

一旦设备连接,它应该向第一个设备发送消息。如果连接的设备多于 1 个,我想发送两条消息。一对所有除了最后连接的客户端。并且向最后连接的客户端发送一条消息。

当我将它放在自定义 API 控制器中并基本上调用操作时,我一直使用的代码完美运行,但这不是我想要的。

我想在没有任何用户交互的情况下在OnConnected 内连接设备后立即发送消息,但是当我将代码放入OnConnected 覆盖时,它会停止工作。它不再发送到特定的客户端(第一次连接和最后一次连接)。

我希望有人能够帮助我解决这个问题,因为我已经敲了几个小时的头了。

    public override System.Threading.Tasks.Task OnConnected()
    {
        UserHandler.ConnectedIds.Add(Context.ConnectionId, UserHandler.ConnectedIds.Count + 1);

        int amountOfConnections = UserHandler.ConnectedIds.Count;
        var lastConnection = UserHandler.ConnectedIds.OrderBy(x => x.Value).LastOrDefault();
        var allExceptLast = UserHandler.ConnectedIds.Take(amountOfConnections - 1).Select(x => x.Key).ToList();

        if (amountOfConnections == 1)
        {
            Clients.Client(UserHandler.ConnectedIds.First().Key).hello("Send to only(also first) one");
        }
        else
        {
            Clients.Clients(allExceptLast).hello("Send to everyone except last");
            Clients.Client(lastConnection.Key).hello("Send to only the last one");
        }

        return base.OnConnected();
    }

【问题讨论】:

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


    【解决方案1】:

    除非我错过了您的问题中的某些内容,否则解决方案对我来说看起来很简单,您只需要切换到使用

    Clients.Caller.hello("Send to only the last one");
    

    而不是试图了解自己谁是最后一个连接的 id。其他的也一样,你可以使用:

    Clients.Others.hello("Send to everyone except last");
    

    您不需要设置所有逻辑,这两行代码可以满足您的需要,并且它们在 OnConnected 内部工作。

    【讨论】:

    • 非常感谢这段代码。它实际上使我的代码更容易!
    【解决方案2】:

    感谢您的所有帮助(支持你们)。实际上发现了问题..它在我的客户内部。我首先订阅了“hello”功能,然后我启动了 HubConnection。一旦我改变了这个顺序,一切都很好。

    它使用以下客户端代码:

        private async Task ConnectToSignalR()
        {
            var hubConnection = new HubConnection("url");
            hubConnection.Headers["x-zumo-application"] = "clientapikey";
    
            IHubProxy proxy = hubConnection.CreateHubProxy("ChatHub");
    
            proxy.On<string>("hello", async (msg) =>
            {
                Console.WriteLine(msg);
            });
    
            await hubConnection.Start();
        }
    

    【讨论】:

      【解决方案3】:

      由于您尚未建立连接,因此此时无法尝试在 OnConnected 中调用您的客户端 .hello() 函数。但是,我们可以定义一个服务器集线器方法,并在我们的连接.done 回调时立即调用它。然后,在我们的新服务器方法中,我们可以重新分配您当前在OnConnected 中拥有的逻辑。

      这将大大改变我们的设置并引入一些额外的步骤,但请注意以下示例...

      // WhateverHub
      public override Task OnConnected()
      {
          return base.OnConnected()
      }
      
      public void AfterConnected()
      {
          // if(stuff) -- whatever if/else first user/last user logic
          // {
              Clients.Caller.hello("message")
          // }
      }
      

      var proxy= $.connection.whateverHub;
      
      proxy.client.hello = function(message) {
          // last step in event chain
      }
      
      $.connection.hub.start().done(function () {
          proxy.server.afterConnected() // call AfterConnected() on hub
      });
      

      所以这里的基本思路是先

      1. 连接 => .done(function() { ... });
      2. 致电server.afterConnected()
      3. 在该方法中执行逻辑
      4. 如果我们对条件满意,请调用我们的 .hello() 客户端函数

      注意 - 此实现适用于 JavaScript 客户端 - 但同样的想法也可以转换为 .net 客户端。这主要是一个架构问题。

      【讨论】:

        【解决方案4】:

        嗯......你正在返回一个任务......所以我认为这可能是问题...... 你应该先执行你的代码,然后返回任务...或者放一个 ContinueWith... 像...

            public override Task OnConnected()
            {
                Task task = new Task(() =>
                    {
                        UserHandler.ConnectedIds.Add(Context.ConnectionId, UserHandler.ConnectedIds.Count + 1);
        
                        int amountOfConnections = UserHandler.ConnectedIds.Count;
                        var lastConnection = UserHandler.ConnectedIds.OrderBy(x => x.Value).LastOrDefault();
                        var allExceptLast = UserHandler.ConnectedIds.Take(amountOfConnections - 1).Select(x => x.Key).ToList();
        
                        if (amountOfConnections == 1)
                        {
                            Clients.Client(UserHandler.ConnectedIds.First().Key).hello("Send to only(also first) one");
                        }
                        else
                        {
                            Clients.Clients(allExceptLast).hello("Send to everyone except last");
                            Clients.Client(lastConnection.Key).hello("Send to only the last one");
                        }
                    });
        
                task.ContinueWith(base.OnConnected());
        
                return task;
            }
        

        我还没有测试过……这只是一个猜测……

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-10-08
          • 1970-01-01
          • 1970-01-01
          • 2021-11-14
          • 1970-01-01
          • 1970-01-01
          • 2016-04-14
          相关资源
          最近更新 更多