SignalR и большое количество групп

Я использую последнюю версию SignalR, и это здорово. Однако недавно я столкнулся с интересной проблемой масштабирования: кажется, что SignalR отправляет все клиентские группы от клиента в строке запроса. Моя система требует, чтобы человек присоединялся к многочисленным группам, которые представляют все проекты, на которые подписан пользователь, и получал уведомления по любому из них.

это большое количество групп (и я использую идентификаторы GUID для идентификаторов) привело к тому, что строка запроса достигла максимального размера, а SignalR перестал работать.

Это то, что Fiddler показывает в веб-форме запроса (с использованием длительного опроса на предмет ошибки 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 помочь в этом отношении?

Спасибо.


person Ali B    schedule 29.09.2012    source источник


Ответы (2)


Поскольку группы передаются через строку запроса в SignalR 0.5.3, у вас есть следующие возможности: a) увеличить максимальный размер строки запроса b) использовать более короткие имена групп c) обрабатывать группировку самостоятельно на сервере и передавать отдельно каждому пользователю

PersistentConnections здесь не поможет, так как Hub API построен на их основе, поэтому вы столкнетесь с той же проблемой.

person Alexander Köplinger    schedule 29.09.2012
comment
Да, в итоге я стал управлять группами на сервере. Кажется, это единственный отказоустойчивый и масштабируемый вариант. - person Ali B; 30.09.2012
comment
@AliB Не могли бы вы опубликовать решение, чтобы помочь другим? - person Marco Alves; 19.08.2014

Я знаю, что вам уже был дан ответ, но есть способ управлять группами на сервере без отправки сообщений каждому клиенту индивидуально. Вы можете реализовать свой собственный 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);

person halter73    schedule 03.10.2012
comment
Я не мог заставить это работать, он не будет транслироваться в группы, которые я укажу в диспетчере (но все равно работает при трансляции для всех). Также обратите внимание, что подпись вашей функции CreateConnection () неверна в v0.5.3, она должна быть Connection CreateConnection(string connectionId, IEnumerable<string> groups, IRequest request) - person Alexander Köplinger; 05.10.2012