SignalR – 发送消息OnConnected

我今天一直在试验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(); } 

除非我错过了你的问题,否则解决方案看起来很简单,你只需要切换到使用

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

而不是试图了解自己谁是最后一个连接ID。 与其他相同,您可以使用:

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

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

感谢所有的帮助(赞成你们)。 实际上发现了问题..它在我的客户端内部。 我首先订阅了’hello’函数,之后我启动了HubConnection。 一旦我改变了这个订单,一切都运行良好。

它使用以下客户端代码:

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

由于您尚未建立连接,因此此时无法在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. Connect => .done(function() { ... });
  2. 调用server.afterConnected()
  3. 在该方法中执行逻辑
  4. 如果我们对条件满意,请调用我们的.hello()客户端函数

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

嗯…你正在返回一个任务…所以我认为这可能是问题……你应该首先执行你的代码,然后返回任务……或者把一个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; } 

我没有测试过……它只是猜测..