I created an almost generic approach to interacting with the SignalR hubs. I had to use a string with if statements in the hubFactory method to create the correct hub that matches the name on the server.
namespace is defined globally as var namespace = namespace || {};
/*global namespace, $ */
/// <reference path="../jquery.signalR-0.5.3.js" />
// file: Scripts\custom\HubsService.js
//
// summary: All SignalR hubs interaction will go through this class so that the classes can be testable.
namespace.HubsService = (function ($, namespace) {
'use strict';
var
startHubConnection = function (callback) {
// start a hub connection if it's not active already (one hub connection per client even if multiple hubs)
// id will be undefined until one is started
if ($.connection.hub.id === undefined) {
$.connection.hub.start(function () { callback(); });
} else {
callback();
}
},
endHubConnection = function () {
// terminates all communication for this client
// call only on logout?, otherwise call a server method to stop the polling
$.connection.hub.stop();
},
setupErrorHandling = function () {
if ($.connection.hub.error) {
$.connection.hub.error(function (e) {
console.log('An error occurred in the hub...' + e.responseText + ' : ' + e);
});
} else {
console.log('Connection hub error handling not available.');
}
},
hubFactory = function (hubName) {
if (hubName === "machineDataHub") {
setupErrorHandling();
return $.connection.machineDataHub;
}
if (hubName === "notificationsHub") {
setupErrorHandling();
return $.connection.notificationsHub;
}
// else if add more here as needed
throw new Error('The hub name: ' + hubName + ' is not valid in HubsService.hubFactory.');
},
getHubId = function () {
return $.connection.Id;
//if (hubName == "machineDataHub") {
// return $.connection.machineDataHub.Id;
//}
//else if (hubName == "notificationsHub") {
// return $.connection.notificationsHub.Id;
//}
},
setHubLogging = function (isLoggingOn) {
$.connection.logging = isLoggingOn;
};
return {
StartHubConnection: startHubConnection,
EndHubConnection: endHubConnection,
HubFactory: hubFactory,
GetHubId: getHubId,
SetHubLogging: setHubLogging
};
}($, namespace));
To call it I have a Knockout ViewModel shell that looks like to setup a notifications service using Toastr
namespace.NotificationsVM = (function (hubsService){
'use strict';
if (hubsService === undefined) {
throw "HubsService must be defined by the caller";
}
var
notificationsHub,
init = function () {
// init for the hub
// call the server NotificationsHub.cs method to start
if (userId === 0 || userId) {
throw new Error("UserId must be defined in GlobalVM before calling init");
}
// same name as the hub on the server
notificationsHub = hubsService.HubFactory("notificationsHub");
// define a callback method from the server
notificationsHub.ReceiveClientNotifications = function (notifications) {
// show the notification(s) with Toastr
namespace.Utilities.ConsoleWrite.log('data: ' + JSON.stringify(notifications));
var i = 0, value, tot;
for (tot = notifications.length; i < tot; i++) {
value = notifications[i];
// toastr.info(value.Message, value.Title);
// info, success, warning, error, match up with the enum
if (value.NotificationTypeId === 1) {
toastr.success(value.Message, value.Title);
} else if (value.NotificationTypeId === 2) {
toastr.info(value.Message, value.Title);
} else if (value.NotificationTypeId === 3) {
toastr.warning(value.Message, value.Title);
} else if (value.NotificationTypeId === 4) {
toastr.error(value.Message, value.Title);
}
}
};
notificationsHub.startClientNotifications(userId).done(function () {
console.log'connected to notification hub for userId ' + userId + '...');
}).fail(function (e) {
// log this with an HTTP call to a WebApi or WCF
console.warn(e);
});
},
startNotifications = function () {
// tell the server to start sending machine data
hubsService.StartHubConnection(function () {
init();
});
},
stopNotifications = function () {
notificationsHub.stopClientNotifications(hubsService.GetHubId()).done(function () {
console.log('stopped connection to notifications hub...');
}).fail(function (e) {
// log this
console.warn(e);
});
};
return {
NotificationsHub: notificationsHub,
StartNotifications: startNotifications,
StopNotifications: stopNotifications,
};
}(namespace.HubsService, namespace);
Formatting from : http://formatmysourcecode.blogspot.com/2006/02/paste-your-text-here.html#links