Signalr (1.0.0-alpha2) Hubs - Можно ли добавить клиентские функции после начала подключения?

Используя Signalr (1.0.0-alpha2), я хочу знать, можно ли добавить клиентские функции после запуска соединения.

Скажем, я создаю свое соединение и хватаю прокси. Затем я добавляю некоторые клиентские функции Server Fired в концентратор, чтобы сделать несколько вещей. Затем я начинаю подключение. Затем я хочу добавить еще несколько функций, запущенных сервером, к моему центральному объекту. Это возможно?

var myHub= $.connection.myHub;
myHub.SomeClientFunction = function() {
   alert("serverside called 'Clients.SomeClientFunction()'");
};
$.connection.hub.start()
   .done(function() {
      myHub.SomeNewClientFunction = function() {
        alert("serverside called 'Clients.SomeNewClientFunction()'");
      }
    })

Этот пример нереалистичен, но я в основном хочу отправить свою переменную myHub другому объекту после того, как концентратор запущен, чтобы подписаться на новые события, которые исходный код не заботился.

Пример из реальной жизни: информационная панель с рядом различных событий хаба (новые посещения сайта, сообщение в чате, ошибка сайта). Я «подписываюсь» после того, как соединение началось, а затем передаю свой прокси-концентратор всем своим различным компонентам пользовательского интерфейса для обработки их конкретных «типов сообщений». Должен ли я создавать отдельные концентраторы для них или я должен иметь возможность добавлять дополнительные клиентские функции Server Fired на лету?


person ncyankee    schedule 21.11.2012    source источник


Ответы (2)


Да, ты можешь. Используйте метод .on.

Пример:

myHub.on('somethingNew', function() {
    alert("This was called after the connection started!");
});

Если вы хотите удалить его позже, используйте метод .off.

person N. Taylor Mullen    schedule 21.11.2012
comment
У вас должна быть хотя бы одна подписка перед вызовом start. - person davidfowl; 22.11.2012
comment
@dfowler это одна подписка на хаб или всего? Также означает ли подписка, что у сервера уже есть функция для вызова? - person Rangoric; 31.12.2012
comment
На хаб. Подписка означает, что у вас есть обратный вызов, определенный на стороне клиента. - person davidfowl; 31.12.2012

У меня точно такая же ситуация. Возможно, вам захочется добавить еще один макет абстракции, если вы пытаетесь вызывать его из нескольких мест.

Вот предварительная версия того, что у меня получилось (машинопись).

Начну с использования. SignalRManager — это мой класс «менеджер», который абстрагирует мой концентратор debuggingHub. У меня есть клиентский метод fooChanged, который запускается на сервере.

Где-то в модуле, который использует SignalR, я просто вызываю метод start, который не перезапускается, если уже запущен.

// ensure signalR is started
SignalRManager.start().done(() =>
{
    $.connection.debuggingHub.server.init();
});

Ваш «модуль» просто регистрирует свой обратный вызов через класс менеджера, и всякий раз, когда запускается клиентский метод SignalR, вызывается ваш обработчик.

// handler for foo changed
SignalRManager.onFooChanged((guid: string) =>
{
    if (this.currentSession().guid == guid)
    {
        alert('changed');
    }
});   

Это простая версия SignalRManager, которая использует jQuery $.Callbacks для передачи запроса максимальному количеству модулей. Конечно, вы можете использовать любой механизм, какой захотите, но этот кажется самым простым.

module RR 
{ 
    export class SignalRManager
    {
        // the original promise returned when calling hub.Start
        static _start: JQueryPromise<any>;

        private static _fooChangedCallback = $.Callbacks();

        // add callback for 'fooChanged' callback
        static onfooChanged(callback: (guid: string) => any)
        {
            SignalRManager._fooChangedCallback.add(callback);
        }

        static start(): JQueryPromise<any>
        {
            if (!SignalRManager._start)
            {
                // callback for fooChanged
                $.connection.debuggingHub.client.fooChanged = (guid: string) =>
                {
                    console.log('foo Changed ' + guid);
                    SignalRManager._fooChangedCallback.fire.apply(arguments);                    
                };

                // start hub and save the promise returned
                SignalRManager._start = $.connection.hub.start().done(() =>
                {
                    console.log('Signal R initialized');
                });
            }

            return SignalRManager._start;
        }
    }
}

Примечание. Для обработки отключений или потери соединений может потребоваться дополнительная работа.

person Simon_Weaver    schedule 28.05.2015