I am having a really frustrating issue that I can't seem to get to the bottom of.
I am using SignalR to push messages to a mobile device and the client method is being fired multiple times. The amount of times it fires grows when I log out which is supposed to cleanup/close/stop the connection.
My Hub looks like the following
public class MyHub:Hub
{
private static string _groupIdentifier = "Test"
public override Task OnConnected()
{
var identity = //grab identity from auth provider
Groups.Add(Context.ConnectionId, string.Format("{0}-{1}", _groupIdentifier, identity.UserId));
return base.OnConnected();
}
public void OnMessageCreated(Message message)
{
IHubContext context = GlobalHost.ConnectionManager.GetHubContext<MessageCreatedEmitter>();
context.Clients.Group(String.Format("{0}-{1}",_groupIdentifier, message.userId)).onMessageCreated(obj);
}
public override Task OnReconnected()
{
var identity = //grab identity from my auth provider
Groups.Add(Context.ConnectionId, string.Format("{0}-{1}", _groupIdentifier, identity.UserId));
return base.OnReconnected();
}
public override Task OnDisconnected(bool stopCalled)
{
var identity = //grab identity from my auth provider
Groups.Remove(Context.ConnectionId, string.Format("{0}-{1}", _groupIdentifier, identity.UserId));
return base.OnDisconnected(stopCalled);
}
}
and my client code looks like the following:
.service('Messages',function($rootScope,$q,$log,User,ENV){
var self = this;
this.proxy = null;
var initializeConnection = function(){
self.proxy = null;
var connection = $.hubConnection(ENV.socketEndpoint,{
qs: {token:User.getToken()},
logging: true,
useDefaultPath: false
});
self.proxy = connection.createHubProxy('myHub');
self.proxy.on('onMessageCreated',function(data){
$rootScope.$emit('Messages:messageReceived',data);
})
connection.start().done(function(){
$log.info('connected');
})
}
var cleanupConnection = function(){
if(self.proxy != undefined && self.proxy != null){
self.proxy.connection.stop();
}
}
$rootScope.$on('UserAuthenticated',function(event,data){
initializeConnection();
});
$rootScope.$on('UserLoggedOut',function(event,data){
cleanupConnection();
});
return self;
}
I have verified (or at least believe I have) the following
OnMessageCreated
method on my hub is only being invoked once.From the behavior so far, it would seem like connections are being made, or the client method is being registered multiple times and sticks around after the connection is closed, but this doesn't seem right and I haven't been able to prove it.
What is causing, or could possible be causing the client method to be fired more than once given the information above?
At this point, I can't verify if it is an Angular issue or a SignalR issue
A SignalR connection can end in any of the following ways: If the client calls the Stop method, a stop message is sent to the server, and both client and server end the SignalR connection immediately.
Microsoft's @aspnet/signalr package makes it possible to leverage both Azure and Angular to create applications that utilize SignalR.
To test reconnect after the server goes down use iisreset. To simulate client connection dropping (good luck) pull the network cable :) Pulling the network cable won't accurately simulate a client connection dropping when you're using Azure SignalR Service.
I would focus on creating the controller in the right way. For example, this kind of situations are there:
If the controller is specified in the $routeProvider and in the HTML template it will get create once for each declaration.
Services are by nature singletons, but what you really can mess around easily (as I have done, too) is in controllers. I once was on situation, where same data was fetched four times.
I would double check all controller calls from templates and routeprovider etc, everywhere you are referencing or needing one.
Having new instances on every logout may refer to a router issue. Maybe coming to root /
context the a controller having the service gets initialized again and again. Then those controllers interpret every action you make in plural and mess is there.
Source: AngularJS Controller execute twice
It could well be that UserAuthenticated event is firing multiple times but it could be handled by placing a $.signalR.connectionState.disconnected
check around the connection start
var initializeConnection = function(){
self.proxy = null;
var connection = $.hubConnection(ENV.socketEndpoint,{
qs: {token:User.getToken()},
logging: true,
useDefaultPath: false
});
self.proxy = connection.createHubProxy('myHub');
self.proxy.on('onMessageCreated',function(data){
$rootScope.$emit('Messages:messageReceived',data);
})
if ($.connection.hub && $.connection.hub.state === $.signalR.connectionState.disconnected){
connection.start().done(function(){
$log.info('connected');
})
}
}
Edit: I don't actually see where you call the OnMessageCreated
method?
Also have you debugged the signalR hub when calling a disconnect? I presume this gets called as normal when a user disconnects, however you also call it on $rootScope.$on('UserLoggedOut'
surely your signalR hub won't be able to identify the user at this point and therefore they will remain in your Group collection? If that is the case you could expect strange behavior such as multiple calls to be raised to there residual Context.ConnectionId
in the group calls.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With