I am trying to send a message from a controller to client(s) group using SignalR. When an event occurs in one of my controllers, I need to push a message using a signalr hub to be displayed like an alert on my clients screens. i know a lot of questions have been asked here, and I've read and tried a lot of them. Since I am new to SignalR some of them even already helped me to put things in place. At the moment everything seems in place. Clients can connect to the hub and join groups and controller can call methods from the hub. But the client never receive the message and I can't figure out why. I suspect that hub's method called by controller don't "see" the clients but I can't understand what's wrong.
Hub's code :
public static class UserHandler
{
public static HashSet<string> ConnectedIds = new HashSet<string>();
}
[HubName("myHub")]
public class MyHub : Hub
{
private static IHubContext hubContext = GlobalHost.ConnectionManager.GetHubContext<MyHub>();
public void Notify(string groupName, string message)
{
Clients.Group(groupName).displayNotification(message);
}
public static void Static_Notify(string groupName, string message)
{
var toto = UserHandler.ConnectedIds.Count();
hubContext.Clients.Group(groupName).displayNotification(message);
hubContext.Clients.All.displayNotification(message);//for testing purpose
}
public Task JoinGroup(string groupName)
{
return Groups.Add(Context.ConnectionId, groupName);
}
public Task LeaveGroup(string groupName)
{
return Groups.Remove(Context.ConnectionId, groupName);
}
public override Task OnConnected()
{
UserHandler.ConnectedIds.Add(Context.ConnectionId);
return base.OnConnected();
}
public override Task OnDisconnected(bool StopCalled)
{
UserHandler.ConnectedIds.Remove(Context.ConnectionId);
return base.OnDisconnected(StopCalled);
}
}
Here is the call from my controller :
//(For simplification and readability I define here variables actually obtained by treating some data )
//I already checked that problem did not come from missing data here
string groupName = "theGroupName";
string message = "My beautifull message.";
//prepare signalR call
var context = GlobalHost.ConnectionManager.GetHubContext<MyHub>();
//Following commented lines are different attempts made based on exemples and answers I found here and on others sites.
//The uncommented one is the one in use at the moment and is also based on an answer (from SO i think)
//context.Clients.Group(_userEmail).displayNotification(message);
//context.Clients.Group(_userEmail).Notify(_userEmail,message);
MyHub.Static_Notify(_userEmail, message);
And here is the client-side code :
$(document).ready(function () {
var userGroup = 'theGroupName';
$.connection.hub.url = 'http://localhost/SignalRHost/signalr';
var theHub = $.connection.myHub;
console.log($.connection)
console.log($.connection.myHub)
theHub.client.displayNotification = function (message) {
console.log('display message');
alert(message);
};
$.connection.hub.start()
.done(function () {
theHub.server.joinGroup(userGroup);
console.log("myHub hub started : " + $.connection.hub.id)
console.log(theHub)
})
.fail(function () {
console.log('myHub hub failed to connect')
});
});
Please help me understand what logic I failed to understand or what error I am missing.
EDIT :
To answer Alisson's comment: The Startup.cs I forgot to show
public void Configuration(IAppBuilder app)
{
app.Map("/signalr", map =>
{
map.UseCors(CorsOptions.AllowAll);
var hubConfiguration = new HubConfiguration { };
map.RunSignalR();
});
}
Important stuff I forgot to mention too :
- The Controller, the hub, and the client are 3 different projects (because of the global application architecture I had to separate hub logic) All are on my localhost IIS but on different ports
- I've set breakpoints on "OnConnected" and "onDiconnected" events and client connects and disconnects normally
Startup.cs
file? – AlissonMyHub.Static_Notify(_userEmail, message);
in your controller, your Hub is calling clients connected to the controllers project, but your clients are actually connected to the SignalRHost project. You should either use one unique project for Hubs and Controllers, or make sure your controller invoke the Hub in the SignalRHost project. – Alissonconsole.log(theHub.client)
and add the result to your question? – Hackerman