Концентраторы Signalr (1.0.0-alpha2) - Можете ли вы добавить функции клиента после того, как было установлено соединение?
Используя 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' другому объекту после того, как концентратор запущен, чтобы подписаться на новые события, о которых исходный код не заботился.
Пример из реальной жизни: панель инструментов с несколькими различными событиями в хабе (новые посещения сайта, сообщения чата, ошибка сайта). Я "подписываюсь" после того, как соединение началось, и затем передаю свой прокси-сервер-концентратор всем моим различным компонентам пользовательского интерфейса для обработки их определенных "типов сообщений". Должен ли я создать отдельные концентраторы для них или я смогу добавить дополнительные функции Client Fired на лету?
2 ответа
Да, ты можешь. Используйте метод.on.
Пример:
myHub.on('somethingNew', function() {
alert("This was called after the connection started!");
});
Если вы хотите удалить его позже, используйте метод.off.
У меня точно такая же ситуация. Возможно, вы захотите добавить другой макет абстракции, если вы пытаетесь вызвать его из нескольких мест.
Вот предварительная версия того, что я придумал (машинопись).
Начну с использования. 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;
}
}
}
Примечание: может потребоваться дополнительная работа для обработки разъединений или потерянных соединений.