2014-03-19 17 views
2

编辑:SignalR 2 - 从服务器发送并非所有的消息通过客户端收到时集线器的多个实例

我一直在做一些额外的测试,这似乎当我运行多个实例只发生承载SignalR集线器的Web角色(我正在使用天蓝色的服务总线背板)。当我运行集线器的单个实例时,我会看到所有消息都传递给客户端。当我运行多个实例,我得到这些症状:

  • 从服务器日志显示,所有的消息是从客户端发送
  • 记录表明,只有一些已接收信息
  • 看使用Wireshark服务器流量而远程的到Azure上的云服务仅捕获客户端接收邮件

我怀疑是客户持有的Web角色的单一实例,并且连接时的消息出现在网络ROL发起e客户端没有连接,即使广播到正确的SignalR连接,客户端也无法收到它。

运行在网站中托管的SignalR中心的多个实例时,其他人有丢失消息的问题吗?有没有解决这个问题的方法?


我有一个异步处理,通过从JavaScript客户端,在通过我们的SignalR中心发回给客户一个或多个消息完成API调用启动。似乎并非所有从SignalR集线器发送的消息都被javascript客户端接收到。下面是与记录消息沿着流动,我得到:

  1. 客户端立即连接到我们的SignalR毂然后调用当前连接ID与我们的内部用户识别符相关联的订阅方法:

    • WebSocket的开
    • 现在监控保持活着的13333.333333333332警告超时和20000
    • 连接丢失超时触发客户中心事件对枢纽“EventHub”
    • 01“订阅”
    • 客户端订阅事件毂:5539368b-5f82-48bd-8ed9-2c5bed3caefa [这是指示器与用户ID相关联的给定的连接ID的后端]
  2. 我开始后端过程应该导致两条消息被发送回这个客户端。从SignalR枢纽内记录表明两个消息被发送(消息列出了与给定的内部用户ID相关联的所有连接 - 从来就得到了在我们的缓存我还没有清理旧的连接):

    • 事件集线器广播控制动作更新给用户124,用于控制动作120在连接5aaea44a-7810-45b5-8119-3ff1fe613d63,4be9ca16-1e31-42bf-91db-798b757a381c,5f9f9962-4f8b-4712-929e-c943e28ca91f,de7135ba-4e16-4e9e -9c38-e8f78ed59636,82e900d1-005e-4bff-95d0-3737632b4671,0cc273f9-04aa-4570-8cd7-993876219e52,2b6db0f7-ab0c-41d3-beb5-3b312107a923,5539368b-5f82-48bd-8ed9-2c5bed3caefa [note备注id从以上列入清单]
    • e向用户124更新关于连接5aaea44a-7810-45b5-8119-3ff1fe613d63,4be9ca16-1e31-42bf-91db-798b757a381c,5f9f9962-4f8b-4712-929e-c943e28ca91f,de7135ba-4e16-4e9e上的控制动作128的通风孔中枢广播控制动作-9c38-e8f78ed59636,82e900d1-005e-4bff-95d0-3737632b4671,0cc273f9-04aa-4570-8cd7-993876219e52,2b6db0f7-ab0c-41d3-beb5-3b312107a923,5539368b-5f82-48bd-8ed9-2c5bed3caefa [note备注id从上述被包括在列表]
  3. 在客户端,我登录时的方法被调用作为消息的结果被发送,并且我看到:

    • 接收从模型事件枢纽d controlActionUpdated消息:controlActionId 120

有时客户端获取全部由中心发来的消息,但更多的时候,它缺少一个或两个。相关的代码片段低于:

客户:

我们angularjs使用通用事件服务。事件的消费者连接并订阅事件的列表如下:

eventing.initialize(['controlActionUpdated', 'subscribed']);

服务看起来是这样的:

var cn; 
var hubProxy; 
var eventsToHandle = []; 

var initialize = function(events){ 
    for(var index = 0; index < events.length; index++){ 
     if(eventsToHandle.indexOf(events[index]) == -1){ 
      eventsToHandle.push(events[index]); 
     } 
    } 
    connect(); 
} 

//call this to connect to the eventing hub and set up client-side receiving methods 
var connect = function(){ 
    cn = $.hubConnection('https://events.xxx.com/'); 
    cn.logging = true; 

    hubProxy = cn.createHubProxy('eventHub'); 

    //subscribe to all events currently indicated to be handled 
    for(var index = 0; index < eventsToHandle.length; index++){ 
     listen(eventsToHandle[index]); 
    } 

    hubProxy.on('subscribed', function (model) { 
     console.log('Client subscribed to event hub: ' + model); 
    }); 

    cn.qs = { "optiAuthToken" : authentication.getAuthToken() }; 
    cn.start().done(function(){ 
     //subscribe to events for this specific user 
     hubProxy.invoke('subscribe'); 
     $rootScope.$broadcast('connectedToHub'); 
    }); 
} 


var listen = function(eventName){ 
    hubProxy.on(eventName, function(model){ 
     $rootScope.$broadcast(eventName, model); 
    }); 
} 

的接收方法,上述$rootScope.$broadcast(eventName, model);电话是:

$scope.$on('controlActionUpdated', function (event, model) { 
    console.log('received controlActionUpdated message from event hub with model: controlActionId ' + model.controlActionId); 
    [further code omitted] 

服务器:

此方法调用我们的缓存以获取executionUserID的连接列表。如果发现至少有一个,它会向该连接列表发送消息。

public async Task MyControlActionUpdated(ControlActionEventModel model, int executingUserID) 
{ 
    EventingConnectionDetails[] currentConnections = await cache.GetCurrentEventHubConnections(executingUserID); 
    if (currentConnections.Length > 0) 
    { 
     Trace.TraceInformation("event hub broadcasting control action updated to user {0} for control action {1} on connections {2}", 
      executingUserID, model.controlActionId, string.Join(", ", currentConnections.Select(c => c.ConnectionID).Distinct())); 
     Clients.Clients(currentConnections.Select(c => c.ConnectionID).Distinct().ToList()).controlActionUpdated(model); 
    } 
    else 
    { 
     Trace.TraceError("attempt to broadcast control action updated to user {0} for control action {1} failed due to no connections", 
      executingUserID, model.controlActionId); 
    } 

}

我看了看周围其他人抱怨缺少客户端从服务器的消息,但没有发现任何东西。有没有人有任何想法,为什么从服务器发送记录的消息没有记录在客户端收到?

我使用的服务总线底板在Azure中以Web角色托管的SignalR 2.0。客户端是AngularJS 1.2.14版。

+0

你在哪里调用MyControlActionUpdated? – halter73

+0

它在异步过程结束时调用 - 从Azure辅助角色中托管的其他服务调用。 – akabak

回答

1

问题是,由于我的部分配置不正确,服务总线背板并未实际工作(我首先在我的依赖解析器上调用UseServiceBus,然后将依赖解析器设置为DI的解析器)。

自我注意:在尝试深入挖掘之前先检查通过服务总线话题的流量。 :)

相关问题