【问题标题】:SignalR Client Method Fired Multiple Times in Angular ServiceSignalR 客户端方法在 Angular 服务中多次触发
【发布时间】:2015-12-01 14:01:16
【问题描述】:

我遇到了一个非常令人沮丧的问题,我似乎无法深入了解。

我正在使用 SignalR 将消息推送到移动设备,并且多次触发客户端方法。当我注销应该清理/关闭/停止连接时,它触发的次数会增加。

我的 Hub 如下所示

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);
    }
}

我的客户端代码如下所示:

.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;
}

我已经验证(或至少相信我拥有)以下内容

  1. 我的集线器上的 OnMessageCreated 方法只被调用一次。
  2. 当我退出移动设备时,连接会关闭或断开。

从目前的行为来看,似乎正在建立连接,或者客户端方法被多次注册并在连接关闭后仍然存在,但这似乎不正确,我一直无法来证明。

鉴于上述信息,是什么导致或可能导致客户端方法被多次触发?

此时,我无法验证是 Angular 问题还是 SignalR 问题

【问题讨论】:

  • 我会将控制台日志放入 $rootScope.$on('UserAuthenticated',function(event,data){ initializeConnection(); });
  • 到底是什么问题?那initializeConnection在注销n次后发送n+1个请求?

标签: angularjs signalr signalr-hub signalr.client


【解决方案1】:

我会专注于以正确的方式创建控制器。比如有这种情况:

如果控制器在 $routeProvider 和 HTML 模板中指定,它将为每个声明创建一次。

服务本质上是单例的,但你真正可以轻松搞定的东西(就像我所做的那样)是在控制器中。我曾经遇到过四次获取相同数据的情况。

我会仔细检查来自模板和路由提供程序等的所有控制器调用,无论你在哪里引用或需要一个。

每次注销时都有新实例可能是指路由器问题。也许来到根/ 上下文,具有服务的控制器一次又一次地被初始化。然后那些控制器以复数形式解释你所做的每一个动作,并且混乱在那里。

来源: AngularJS Controller execute twice

【讨论】:

    【解决方案2】:

    很可能是 UserAuthenticated 事件触发了多次,但可以通过在连接开始周围放置 $.signalR.connectionState.disconnected 检查来处理它

    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');
            })
    
        }
    
    }
    

    编辑:我实际上没有看到你在哪里调用OnMessageCreated 方法?

    在调用断开连接时,您是否也调试过 signalR 集线器?我认为当用户断开连接时这会正常调用,但是您也可以在 $rootScope.$on('UserLoggedOut' 上调用它,您的 signalR 集线器此时肯定无法识别用户,因此它们将保留在您的组集合中?如果是这种情况,您可能会遇到奇怪的行为,例如在群组通话中会引发多个调用,以向剩余的 Context.ConnectionId 提出。

    【讨论】:

    • 我试过这个,用户身份验证只被触发一次,但onMessageCreated被多次触发
    猜你喜欢
    • 2014-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-08
    • 2015-05-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多