Reputation:
Edit: David Fowler requested for the full code to attempt to replicate the problem. Here is the full code
In addition to the code reproduced here, I have also uploaded a complete Visual Studio 2010 solution to the following URL
http://www.sendspace.com/file/lfeurf (URL has now expired and no longer works)
Please feel free to download and test it.
Here are my findings
Original question: I am using Signalr 1.0.0-rc1 in a MVC3 website. My clients sometimes need to belong to multiple groups. Here is the code in my Hub and client side javascript
Client side javascript and HTML
<script type="text/javascript">
//start signalr
var message = $.connection.messageHub;
// Declare a function on the message hub so the server can invoke it
message.client.send = function (message) {
alert(message);
}
// Start the connection and join groups
$.connection.hub.start();
//bind click event of button to invoke send function on server
$(document).ready(function () {
$("#target").click(function () {
message.server.send("Hello from signalr");
});
});
</script>
<button id="target">Click to send message to other clients</button>
Server side Hub
public class MessageHub: Hub
{
public Task AddGroups()
{
//add 1st group
Groups.Add(Context.ConnectionId, "foo");
//add 2nd group
return Groups.Add(Context.ConnectionId, "foobar");
}
//this method will be called from the client
public void Send(string message)
{
Clients.OthersInGroup("foobar").send(message);
}
//automatically join groups when client first connects
public override Task OnConnected()
{
return AddGroups();
}
//rejoin groups if client disconnects and then reconnects
public override Task OnReconnected()
{
return AddGroups();
}
}
The above code should add two groups to each client when they first connect but it does not work. I stepped through the C# code using a debugger and no errors are being thrown. I also dont see any javascript errors using Chrome's console but the Send function is not being called on the clients. I then changed the AddGroups() method to add only one group as shown below
public Task AddGroups()
{
//dont add first group
//Groups.Add(Context.ConnectionId, "foo");
//add only second group
return Groups.Add(Context.ConnectionId, "foobar");
}
Now my application works perfectly. How do I add a second group? It looks like I have misunderstood joining multiple groups. Could anyone show me the right way to do it?
Upvotes: 5
Views: 13727
Reputation: 725
MyHub.cs
public async Task Subscribe(IEnumerable<string> groups)
{
foreach(var group in groups)
{
await Groups.Add(Context.ConnectionId, group);
}
}
Javascript:
$.connection.hub.start().done(function () {
var groups = ["foo","bar"];
tileHub.server.subscribe(groups)
});
Upvotes: 2
Reputation: 15244
Your issues seems to be that return Groups.Add(Context.ConnectionId, "foobar");
in AddToGroups
is timing out after 5 seconds. The Task
returned from Groups.Add
doesn't complete until SignalR verifies that the client with the specified connectionId
has received the add to group command. If this doesn't happen within 5 seconds the Task
is cancelled. It appears there is currently a bug preventing waiting on Groups.Add
inside of OnConnected
and OnReconnected
.
Since you are returning the cancelled Task
from OnConnected
and OnReconnected
, the server is preventing the client from establishing a connection.
A workaround is to ignore the Task
returned from Groups.Add
like so:
public class MessageHub: Hub
{
public Task AddGroups()
{
//add 1st group
Groups.Add(Context.ConnectionId, "foo");
//add 2nd group
return Groups.Add(Context.ConnectionId, "foobar");
}
//this method will be called from the client
public void Send(string message)
{
Clients.OthersInGroup("foobar").send(message);
}
//automatically join groups when client first connects
public override Task OnConnected()
{
AddGroups();
return base.OnConnected();
}
//rejoin groups if client disconnects and then reconnects
public override Task OnReconnected()
{
AddGroups();
return base.OnReconnected();
}
}
Upvotes: 7