I\'ve been experimenting with SignalR today and It\'s really neat. Basically what I wanted to achieve is the following:
As soon as a device connects it should send a mes
well... you are returning a task... so i think that may be the issue... you should first execute your code and then return the task... or put a ContinueWith... like...
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;
}
I haven't tested that... its just a guess..
Unless I miss something from your question, the solution looks pretty simple to me, you just need to switch to using
Clients.Caller.hello("Send to only the last one");
instead of trying to understand yourself who's the last connected id. Same for the other ones, you can use:
Clients.Others.hello("Send to everyone except last");
You do not need all the logic you setup, those 2 lines do what you need, and they work inside OnConnected
.
Thanks for all the help (upvoted you guys). Actually found the problem.. it was inside my client. I first subscribed to the 'hello' function and after that I started the HubConnection. As soon as I changed this order everything worked fine.
It worked with the following client code:
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();
}
Since you haven't established a connection yet, trying to call your client .hello()
function within OnConnected
is not possible at this point. However, we can define a server hub method and immediately call that upon our connection .done
callback. Then, in our new server method we can reallocate the logic you currently have in OnConnected
.
This will change our setup quite a bit and introduce some additional steps, but observe the following example...
// 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
});
So the basic idea here is to first
.done(function() { ... });
server.afterConnected()
.hello()
client functionNote - this implementation is for a JavaScript client - but the same idea can be translated to a .net client. This is mostly an architectural issue.