由于手头有一个AngularJS项目,而其中消息模块就是采用SignalR来推送。AngularJS就像天生需要SignalR一样,因为他们都需要很快。其实更在意的是WebSocket在AngularJS的应用,而当前只是一个小试验,但效果真的非常好。这一篇文章,我们围绕AngularJS中如何应用SignalR,所以你看到的更多会是JavaScript脚本。

项目是以ASP.NET API作为服务端、OAuth2票据令牌认证、AngularJS做为前端、中间全部采用JSON作为数据传输。

依赖jQuery.SignalR.js

这是必须的,而SignalR客户端脚本库又是以插件的形式,所以不管未来如何更新,都不担心脚本的变动而倒置AngularJS的改动,要知道AngularJS项目的JS脚本管理要控制得非常严谨。

Hub代理脚本

其实我在SignalR JavaScript 客户端已经非常详细的描述过关于如果创建代理脚本,但有个缺点就是他是全局式的,而对于AngularJS而言不建议使用这种全局式的,所以我们需要手动的创建代理脚本部分;并且把它当作一个 factory,这样对于多个Controller是可以共享数据的。

这里有个github的项目,完全可以满足我们的需求,非常简单,我把代理贴出来:

angular.module('SignalR', []) .constant('$', $) .factory('Hub', ['$', function ($) { //This will allow same connection to be used for all Hubs //It also keeps connection as singleton. var globalConnections = []; function initNewConnection(options) { var connection = null; if (options && options.rootPath) { connection = $.hubConnection(options.rootPath, { useDefaultPath: false }); } else { connection = $.hubConnection(); } connection.logging = (options && options.logging ? true : false); return connection; } function getConnection(options) { var useSharedConnection = !(options && options.useSharedConnection === false); if (useSharedConnection) { return typeof globalConnections[options.rootPath] === 'undefined' ? globalConnections[options.rootPath] = initNewConnection(options) : globalConnections[options.rootPath]; } else { return initNewConnection(options); } } return function (hubName, options) { var Hub = this; Hub.connection = getConnection(options); Hub.proxy = Hub.connection.createHubProxy(hubName); Hub.on = function (event, fn) { Hub.proxy.on(event, fn); }; Hub.invoke = function (method, args) { return Hub.proxy.invoke.apply(Hub.proxy, arguments) }; Hub.disconnect = function () { Hub.connection.stop(); }; Hub.connect = function () { return Hub.connection.start(options.transport ? { transport: options.transport } : null); }; if (options && options.listeners) { angular.forEach(options.listeners, function (fn