2012-09-29 30 views
1

我使用SignalR的最新版本,它很棒。不过,我最近遇到了一个有趣的扩展问题:看起来SignalR从查询字符串中的客户端发送了所有客户端的组。我的系统要求一个人加入许多组,这些组代表用户订阅的所有项目,并接收任何项目的通知。SignalR和大量的组

这大量的组(和我使用GUID的ID)导致查询字符串达到其最大大小,并SignalR停止工作。

这是提琴手显示请求的网页表单(使用Azure的错误长轮询):

transport longPolling 
connectionId bbed6f35-8379-4be3-ac28-ef3e618382ae 
connectionData [{"name":"jethub"}] 
messageId 85 
groups ["JetHub.f9f81bcc-8417-46bd-bae5-c4134972601d","JetHub.5139a8de-04c2-48da-9427-39666e52fabd","JetHub.6b12e333-4d22-47c3-8587-7a9ad5026184","JetHub.252ea279-7a71-40e7-b03c-7d63e69f07ab","JetHub.a4843a77-1e6d-4693-b3de-b392ef465410","JetHub.27feb53a-3c2d-4b11-92f7-dbdffb874b25","JetHub.8840dfcf-e6be-4b72-965b-b282a60446e8","JetHub.bf7d3301-6fc0-4499-bee8-fe22f1bc2281","JetHub.655cba0e-7f72-402c-b80b-dcb740546163","JetHub.85d817e2-67a3-4291-b564-5320598339f6","JetHub.e3079263-3f6e-4a54-ad88-0dfc5dd2ce18","JetHub.33f00a67-9b05-4293-8119-4617e2fed9b0","JetHub.6323cfe8-fb81-4716-b553-79b9d72641a5","JetHub.b4359f8a-030a-4ac9-aacd-c05b42163bcc", ... many more] 

我知道我可以在IIS中增加查询字符串大小,但有没有更好的方式来管理组,还是应该尝试创建我的服务器端分组方案并分别向每个客户端进行广播? PersistenConnections可以在这方面提供帮助吗?

谢谢。

回答

3

由于组在SignalR 0.5.3通过查询字符串roundtripped,您有以下选择: 一)增加最大查询字符串大小 B)使用较短的组名 三)处理在服务器上分组自己和单独播放给每个用户

因为Hub API是建立在它们之上的,所以PersistentConnections在这里没有帮助,所以你会遇到同样的问题。

+0

是的,我最终管理服务器上的组。似乎是唯一的故障安全和可扩展选项。 –

+3

@AliB你可以发布解决方案来帮助别人吗? –

2

我知道这已经得到了您的满意回答,但是有一种管理服务器上组的方式,而无需单独向每个客​​户端发送消息。你可以实现自己的HubDispatcher:

using System.Collections.Generic; 
using SignalR; 
using SignalR.Hubs; 

namespace My.Hubs 
{ 
    public class MyHubDispatcher : HubDispatcher 
    { 
     public MyHubDispatcher() : base("/myhubs") { } 

     protected override Connection CreateConnection(string connectionId, IEnumerable<string> signals, IEnumerable<string> groups) 
     { 
      //ex: IEnumerable<string> myGroups = new string[] { "MyHub.MyGroup", "MyHub.MyOtherGroup", "MyOtherHub.MyGroup" }; 
      IEnumerable<string> myGroups = GetGroups(connectionId); 
      return base.CreateConnection(connectionId, signals, myGroups); 
     } 
    } 
} 

然后,您可以设置路由像任何其他PersistentConnection:

using System.Web; 
using System.Web.Routing; 
using SignalR; 

namespace My 
{ 
    // Note: For instructions on enabling IIS6 or IIS7 classic mode, 
    // visit http://go.microsoft.com/?LinkId=9394801 

    public class Application : HttpApplication 
    { 
     protected void Application_Start() 
     { 
      RouteTable.Routes.MapConnection<Hubs.MyHubDispatcher>("myhubs", "myhubs/{*operation}"); 
      RouteConfig.RegisterRoutes(RouteTable.Routes); 
     } 
    } 
} 

然后你可以使用组上你集线器像通常那样:

using SignalR.Hubs; 

namespace My.Hubs 
{ 
    public class MyHub : Hub 
    { 
     public void AlertClients(string id, int duration) 
     { 
      Clients["MyGroup"].Alert("MyGroup"); 
      Clients["MyOtherGroup"].Alert("MyOtherGroup"); 
     } 
    } 
} 

如果您使用JS客户端,您可以简单地将脚本包含在~/myhubs/hubs而不是~/signalr/hubs。如果您使用.NET客户端,您只需使用new Client.Hubs.HubConnection("http://foo/myhubs", useDefaultUrl: false);

+0

我无法工作,它不会广播到我在调度员指定的组中(但在向所有人广播时仍然有效)。还要注意你的CreateConnection()函数的签名在v0.5.3中是错误的,应该是'Connection CreateConnection(string connectionId,IEnumerable groups,IRequest request)' –