2016-08-04 135 views
1

这个问题是不是与Scaleout和SignalR Azure的服务总线。我想在我的SignalR网络套接字应用程序中构建一个Service Bus侦听器(例如OnMessage),然后将该消息相应地分发给连接的用户。消息将从各种独立运行的服务发布到集中式服务总线中,并且连接到Web套接字服务器的UI /浏览器应接收这些消息。Azure的服务总线的集成与SignalR

选项1:我可以将异步任务添加到集线器方法中,以订阅服务总线并由连接的用户进行过滤。问题在于它使用了线程池中的一个额外线程,并且将为执行此操作,每个用户已启动套接字连接。我们的应用程序可以轻松启动每个标签打开5-10个或更多的套接字。

选项2:我可以将一个任务添加到SignalR Startup.Configuration方法,然后接收所有消息并将它们分发给正确的连接用户。我在这里遇到的问题是,我无法访问用于发送到浏览器的客户端对象。

我觉得SignalR和服务总线是一个很好的补充,相互支持近乎实时的通信,但我能找到很少实现这样的场景。我觉得这应该是一个常见的情况。也许我错过了一些明显的设计模式,这将是一个更好的解决方案。

回答

0

我能想出解决办法。在SignalR Startup.Configuration方法我添加到启动监听的方法和在该方法我叫GlobalHost.ConnectionManager.GetHubContext。目前这不会发送给个人用户,但我会添加某种连接管理器来处理该问题。

public void startServiceBusListener() 
{ 

    // setup subcsription 
    var namespaceManager = NamespaceManager.CreateFromConnectionString(connectionString); 
    if (!namespaceManager.SubscriptionExists("myTopic", Environment.MachineName)) 
     namespaceManager.CreateSubscription("myTopic", Environment.MachineName); 

    SubscriptionClient busClient = SubscriptionClient.CreateFromConnectionString(connectionString, "myTopic", Environment.MachineName); 

    // Configure the callback options. 
    OnMessageOptions options = new OnMessageOptions(); 
    options.AutoComplete = false; 
    options.AutoRenewTimeout = TimeSpan.FromMinutes(1); 

    receiveTask = Task.Run(() => 
    { 
     // handle new messages 
     busClient.OnMessage((message) => 
     { 
      try 
      { 
       Notification note = message.GetBody<Notification>(); 
       string notification = JsonConvert.SerializeObject(note); 
       GlobalHost.ConnectionManager.GetHubContext<DispatchHub>().Clients.All.notify(notification); 
       // Remove message from subscription. 
       message.Complete(); 
      } 
      catch (Exception) 
      { 
       // Indicates a problem, unlock message in subscription. 
       message.Abandon(); 
      } 
     }, options); 
    }, cts.Token); 
}