[英]SignalR - Send message 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");
你不需要你设置的所有逻辑,这2行做你需要的,它们在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<string>("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
});
所以这里的基本想法是首先
.done(function() { ... });
server.afterConnected()
.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;
}
我没有测试过......它只是猜测..
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.