Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Added hub events support to JavaScript client:

- API mimics the .NET client hub API (createProxy, on, invoke, etc.)
- Update MouseMove sample to use hub events
  • Loading branch information...
commit 97c984754f20bd6dda8c343983d679b8f65093c8 1 parent f6aa43b
@DamianEdwards DamianEdwards authored
View
1  SignalR.Client.JS/SignalR.Client.JS.csproj
@@ -59,6 +59,7 @@
<Reference Include="System.EnterpriseServices" />
</ItemGroup>
<ItemGroup>
+ <Content Include="jquery.signalR.hubs.js" />
<Content Include="jquery.signalR.transports.common.js" />
<Content Include="jquery.signalR.transports.webSockets.js" />
<Content Include="jquery.signalR.transports.serverSentEvents.js" />
View
3  SignalR.Client.JS/build.ps1
@@ -5,7 +5,8 @@ $files =
"jquery.signalR.transports.webSockets.js",
"jquery.signalR.transports.serverSentEvents.js",
"jquery.signalR.transports.foreverFrame.js",
- "jquery.signalR.transports.longPolling.js"
+ "jquery.signalR.transports.longPolling.js",
+ "jquery.signalR.hubs.js"
# Run JSHint against files
Write-Host "Running JSHint..." -ForegroundColor Yellow
View
178 SignalR.Client.JS/jquery.signalR.hubs.js
@@ -0,0 +1,178 @@
+/*global window:false */
+/// <reference path="jquery.signalR.core.js" />
+
+(function ($, window) {
+ "use strict";
+
+ // we use a global id for tracking callbacks so the server doesn't have to send extra info like hub name
+ var callbackId = 0,
+ callbacks = {};
+
+ // Array.prototype.map
+ if (!Array.prototype.hasOwnProperty("map")) {
+ Array.prototype.map = function (fun, thisp) {
+ var arr = this,
+ i,
+ length = arr.length,
+ result = [];
+ for (i = 0; i < length; i += 1) {
+ if (arr.hasOwnProperty(i)) {
+ result[i] = fun.call(thisp, arr[i], i, arr);
+ }
+ }
+ return result;
+ };
+ }
+
+ function getArgValue(a) {
+ return $.isFunction(a) ? null : ($.type(a) === "undefined" ? null : a);
+ }
+
+ // hubProxy
+ function hubProxy(hubConnection, hubName) {
+ /// <summary>
+ /// Creates a new proxy object for the given hub connection that can be used to invoke
+ /// methods on server hubs and handle client method invocation requests from the server.
+ /// </summary>
+ return new hubProxy.fn.init(hubConnection, hubName);
+ }
+
+ hubProxy.fn = hubProxy.prototype = {
+ init: function (connection, hubName) {
+ this.state = {};
+ this.connection = connection;
+ this.hubName = hubName;
+ },
+
+ on: function (eventName, callback) {
+ /// <summary>Wires up a callback to be invoked when a invocation request is received from the server hub.</summary>
+ /// <param name="eventName" type="String">The name of the hub event to register the callback for.</param>
+ /// <param name="callback" type="Function">The callback to be invoked.</param>
+ var self = this;
+ $(self).bind(eventName, function (e, data) {
+ callback.apply(self, data);
+ });
+ return self;
+ },
+
+ invoke: function (methodName) {
+ /// <summary>Invokes a server hub method with the given arguments.</summary>
+ /// <param name="methodName" type="String">The name of the server hub method.</param>
+
+ var self = this,
+ args = $.makeArray(arguments).slice(1),
+ userCallback = args[args.length - 1], // last argument
+ methodArgs = $.type(userCallback) === "function" ? args.slice(0, -1) /* all but last */ : args,
+ argValues = methodArgs.map(getArgValue),
+ data = { hub: self.hubName, method: methodName, args: argValues, state: self.state, id: callbackId },
+ d = $.Deferred(),
+ callback = function (result) {
+ $.extend(this.state, result.State);
+
+ if (result.Error) {
+ // Server hub method threw an exception, log it & reject the deferred
+ if (result.StackTrace) {
+ self.connection.log(result.Error + "\n" + result.StackTrace);
+ }
+ d.rejectWith(self, [result.Error]);
+ } else {
+ // Server invocation succeeded, invoke any user callback & resolve the deferred
+ if ($.type(userCallback) === "function") {
+ userCallback.call(self, result.Result);
+ }
+ d.resolveWith(self, [result.Result]);
+ }
+ };
+
+ callbacks[callbackId.toString()] = { scope: self, method: callback };
+ callbackId += 1;
+ self.connection.send(window.JSON.stringify(data));
+
+ return d.promise();
+ }
+ };
+
+ hubProxy.fn.init.prototype = hubProxy.fn;
+
+
+ // hubConnection
+ function hubConnection(url) {
+ /// <summary>Creates a new hub connection.</summary>
+ /// <param name="url" type="String">[Optional] The hub route url, defaults to "/signalr"</param>
+ if (!url) {
+ url = "/signalr";
+ }
+ return new hubConnection.fn.init(url);
+ }
+
+ hubConnection.fn = hubConnection.prototype = $.connection();
+
+ hubConnection.fn.init = function (url, qs, logging) {
+ var connection = this;
+
+ $.signalR.fn.init.call(connection, url, qs, logging);
+
+ // Object to store hub proxies for this connection
+ connection.proxies = {};
+
+ // Wire up the sending handler
+ connection.sending(function () {
+ var clientHubs = [];
+
+ $.each(this.proxies, function (key) {
+ clientHubs.push({ name: key });
+ });
+
+ this.data = window.JSON.stringify(clientHubs);
+ });
+
+ // Wire up the received handler
+ connection.received(function (data) {
+ var proxy, dataCallbackId, callback;
+ if (!data) {
+ return;
+ }
+
+ if (typeof(data.Id) !== "undefined") {
+ // We received the return value from a server method invocation, look up callback by id and call it
+ dataCallbackId = data.Id.toString();
+ callback = callbacks[dataCallbackId];
+ if (callback) {
+ // Delete the callback from the proxy
+ callbacks[dataCallbackId] = null;
+ delete callbacks[dataCallbackId];
+
+ // Invoke the callback
+ callback.method.call(callback.scope, data);
+ }
+ } else {
+ // We received a client invocation request, i.e. broadcast from server hub
+ // Trigger the local invocation event
+ proxy = this.proxies[data.Hub];
+ $.extend(proxy.state, data.State);
+ $(proxy).trigger(data.Method, [data.Args]);
+ }
+ });
+ };
+
+ hubConnection.fn.createProxy = function (hubName) {
+ /// <summary>
+ /// Creates a new proxy object for the given hub connection that can be used to invoke
+ /// methods on server hubs and handle client method invocation requests from the server.
+ /// </summary>
+ /// <paramater name="hubName" type="String">
+ /// The name of the hub on the server to create the proxy for.
+ /// </parameter>
+ var proxy = this.proxies[hubName];
+ if (!proxy) {
+ proxy = hubProxy(this, hubName);
+ this.proxies[hubName] = proxy;
+ }
+ return proxy;
+ };
+
+ hubConnection.fn.init.prototype = hubConnection.fn;
+
+ $.hubConnection = hubConnection;
+
+}(window.jQuery, window));
View
29 samples/SignalR.Hosting.AspNet.Samples/Hubs/MouseTracking/MouseTracking.js
@@ -1,13 +1,18 @@
-$(function () {
+/// <reference path="../../Scripts/jquery-1.6.2.js" />
+/// <reference path="../../Scripts/jquery.signalR.js" />
+
+$(function () {
// Pure client side hub
- var signalR = $.connection;
- signalR.mouseTracking.moveMouse = function (id, x, y) {
- if (id == this.id) {
+ var hubConnection = $.hubConnection(),
+ hub = hubConnection.createProxy('MouseTracking');
+
+ hub.on('moveMouse', function (id, x, y) {
+ if (id == this.state.id) {
return;
}
updateCursor(id, x, y);
- };
+ });
function updateCursor(id, x, y) {
var e = document.getElementById(id);
@@ -22,14 +27,14 @@
e.css('top', y);
}
-
- signalR.hub.start({ transport: activeTransport }, function () {
- signalR.mouseTracking.join(function () {
-
+ hubConnection.start({ transport: activeTransport })
+ .done(function () {
+ return hub.invoke('Join');
+ })
+ .done(function () {
$(document).mousemove(function (e) {
- signalR.mouseTracking.move(e.pageX, e.pageY);
- updateCursor(signalR.mouseTracking.id, e.pageX, e.pageY);
+ hub.invoke('Move', e.pageX, e.pageY);
+ updateCursor(hub.state.id, e.pageX, e.pageY);
});
});
- });
});
View
2  samples/SignalR.Hosting.AspNet.Samples/Hubs/MouseTracking/index.htm
@@ -8,7 +8,7 @@
<script src="../../Scripts/jquery-1.6.2.min.js" type="text/javascript"></script>
<script src="../../Scripts/json2.min.js" type="text/javascript"></script>
<script src="../../Scripts/jquery.signalR.js" type="text/javascript"></script>
- <script src="../../signalr/hubs" type="text/javascript"></script>
+ <!--<script src="../../signalr/hubs" type="text/javascript"></script>-->
<script src="MouseTracking.js" type="text/javascript"></script>
</head>
<body>
View
12 samples/SignalR.Hosting.AspNet.Samples/Scripts/hubs.js
@@ -144,7 +144,7 @@
callbacks[callbackId.toString()] = { scope: hub, callback: cb };
callbackId += 1;
hub._.connection().send(window.JSON.stringify(data));
- return d;
+ return d.promise();
}
// Create hub signalR instance
@@ -171,7 +171,7 @@
demo: {
_: {
hubName: 'demo',
- ignoreMembers: ['addToGroups', 'complexArray', 'complexType', 'doSomethingAndCallError', 'dynamicTask', 'genericTaskTypedAsPlain', 'genericTaskWithException', 'getValue', 'multipleCalls', 'overload', 'passingDynamicComplex', 'plainTask', 'readStateValue', 'setStateValue', 'simpleArray', 'taskWithException', 'unsupportedOverload', 'namespace', 'ignoreMembers', 'callbacks'],
+ ignoreMembers: ['addToGroups', 'complexArray', 'complexType', 'doSomethingAndCallError', 'dynamicInvoke', 'dynamicTask', 'genericTaskTypedAsPlain', 'genericTaskWithException', 'getValue', 'multipleCalls', 'overload', 'passingDynamicComplex', 'plainTask', 'readStateValue', 'setStateValue', 'simpleArray', 'taskWithException', 'testGuid', 'unsupportedOverload', 'namespace', 'ignoreMembers', 'callbacks'],
connection: function () { return signalR.hub; }
},
@@ -241,6 +241,14 @@
unsupportedOverload: function (x, callback) {
return serverCall(this, "UnsupportedOverload", $.makeArray(arguments));
+ },
+
+ testGuid: function (callback) {
+ return serverCall(this, "TestGuid", $.makeArray(arguments));
+ },
+
+ dynamicInvoke: function (method, callback) {
+ return serverCall(this, "DynamicInvoke", $.makeArray(arguments));
}
},
drawingPad: {
View
184 samples/SignalR.Hosting.AspNet.Samples/Scripts/jquery.signalR.js
@@ -303,9 +303,8 @@
transports.push($.type(transport) === "string" ? "" + transport : transport);
}
});
- } else if ($.type(config.transport) === "object" ||
- $.inArray(config.transport, supportedTransports) >= 0) {
- // specific transport provided, as object or a named transport, e.g. "longPolling"
+ } else if ($.type(config.transport) === "object" || $.inArray(config.transport, supportedTransports) >= 0) {
+ // specific transport provided, as object or a named transport, e.g. "longPolling"
transports.push(config.transport);
} else { // default "auto"
transports = supportedTransports;
@@ -1284,3 +1283,182 @@
};
}(window.jQuery, window));
+/* jquery.signalR.hubs.js */
+/*global window:false */
+/// <reference path="jquery.signalR.core.js" />
+
+(function ($, window) {
+ "use strict";
+
+ // we use a global id for tracking callbacks so the server doesn't have to send extra info like hub name
+ var callbackId = 0,
+ callbacks = {};
+
+ // Array.prototype.map
+ if (!Array.prototype.hasOwnProperty("map")) {
+ Array.prototype.map = function (fun, thisp) {
+ var arr = this,
+ i,
+ length = arr.length,
+ result = [];
+ for (i = 0; i < length; i += 1) {
+ if (arr.hasOwnProperty(i)) {
+ result[i] = fun.call(thisp, arr[i], i, arr);
+ }
+ }
+ return result;
+ };
+ }
+
+ function getArgValue(a) {
+ return $.isFunction(a) ? null : ($.type(a) === "undefined" ? null : a);
+ }
+
+ // hubProxy
+ function hubProxy(hubConnection, hubName) {
+ /// <summary>
+ /// Creates a new proxy object for the given hub connection that can be used to invoke
+ /// methods on server hubs and handle client method invocation requests from the server.
+ /// </summary>
+ return new hubProxy.fn.init(hubConnection, hubName);
+ }
+
+ hubProxy.fn = hubProxy.prototype = {
+ init: function (connection, hubName) {
+ this.state = {};
+ this.connection = connection;
+ this.hubName = hubName;
+ },
+
+ on: function (eventName, callback) {
+ /// <summary>Wires up a callback to be invoked when a invocation request is received from the server hub.</summary>
+ /// <param name="eventName" type="String">The name of the hub event to register the callback for.</param>
+ /// <param name="callback" type="Function">The callback to be invoked.</param>
+ var self = this;
+ $(self).bind(eventName, function (e, data) {
+ callback.apply(self, data);
+ });
+ return self;
+ },
+
+ invoke: function (methodName) {
+ /// <summary>Invokes a server hub method with the given arguments.</summary>
+ /// <param name="methodName" type="String">The name of the server hub method.</param>
+
+ var self = this,
+ args = $.makeArray(arguments).slice(1),
+ userCallback = args[args.length - 1], // last argument
+ methodArgs = $.type(userCallback) === "function" ? args.slice(0, -1) /* all but last */ : args,
+ argValues = methodArgs.map(getArgValue),
+ data = { hub: self.hubName, method: methodName, args: argValues, state: self.state, id: callbackId },
+ d = $.Deferred(),
+ callback = function (result) {
+ $.extend(this.state, result.State);
+
+ if (result.Error) {
+ // Server hub method threw an exception, log it & reject the deferred
+ if (result.StackTrace) {
+ self.connection.log(result.Error + "\n" + result.StackTrace);
+ }
+ d.rejectWith(self, [result.Error]);
+ } else {
+ // Server invocation succeeded, invoke any user callback & resolve the deferred
+ if ($.type(userCallback) === "function") {
+ userCallback.call(self, result.Result);
+ }
+ d.resolveWith(self, [result.Result]);
+ }
+ };
+
+ callbacks[callbackId.toString()] = { scope: self, method: callback };
+ callbackId += 1;
+ self.connection.send(window.JSON.stringify(data));
+
+ return d.promise();
+ }
+ };
+
+ hubProxy.fn.init.prototype = hubProxy.fn;
+
+
+ // hubConnection
+ function hubConnection(url) {
+ /// <summary>Creates a new hub connection.</summary>
+ /// <param name="url" type="String">[Optional] The hub route url, defaults to "/signalr"</param>
+ if (!url) {
+ url = "/signalr";
+ }
+ return new hubConnection.fn.init(url);
+ }
+
+ hubConnection.fn = hubConnection.prototype = $.connection();
+
+ hubConnection.fn.init = function (url, qs, logging) {
+ var connection = this;
+
+ $.signalR.fn.init.call(connection, url, qs, logging);
+
+ // Object to store hub proxies for this connection
+ connection.proxies = {};
+
+ // Wire up the sending handler
+ connection.sending(function () {
+ var clientHubs = [];
+
+ $.each(this.proxies, function (key) {
+ clientHubs.push({ name: key });
+ });
+
+ this.data = window.JSON.stringify(clientHubs);
+ });
+
+ // Wire up the received handler
+ connection.received(function (data) {
+ var proxy, dataCallbackId, callback;
+ if (!data) {
+ return;
+ }
+
+ if (typeof(data.Id) !== "undefined") {
+ // We received the return value from a server method invocation, look up callback by id and call it
+ dataCallbackId = data.Id.toString();
+ callback = callbacks[dataCallbackId];
+ if (callback) {
+ // Delete the callback from the proxy
+ callbacks[dataCallbackId] = null;
+ delete callbacks[dataCallbackId];
+
+ // Invoke the callback
+ callback.method.call(callback.scope, data);
+ }
+ } else {
+ // We received a client invocation request, i.e. broadcast from server hub
+ // Trigger the local invocation event
+ proxy = this.proxies[data.Hub];
+ $.extend(proxy.state, data.State);
+ $(proxy).trigger(data.Method, [data.Args]);
+ }
+ });
+ };
+
+ hubConnection.fn.createProxy = function (hubName) {
+ /// <summary>
+ /// Creates a new proxy object for the given hub connection that can be used to invoke
+ /// methods on server hubs and handle client method invocation requests from the server.
+ /// </summary>
+ /// <paramater name="hubName" type="String">
+ /// The name of the hub on the server to create the proxy for.
+ /// </parameter>
+ var proxy = this.proxies[hubName];
+ if (!proxy) {
+ proxy = hubProxy(this, hubName);
+ this.proxies[hubName] = proxy;
+ }
+ return proxy;
+ };
+
+ hubConnection.fn.init.prototype = hubConnection.fn;
+
+ $.hubConnection = hubConnection;
+
+}(window.jQuery, window));
View
2  samples/SignalR.Hosting.AspNet.Samples/Scripts/jquery.signalR.min.js
@@ -6,4 +6,4 @@
* Licensed under the MIT.
* https://github.com/SignalR/SignalR/blob/master/LICENSE.md
*/
-(function(n,t){"use strict";if(typeof n!="function")throw"SignalR: jQuery not found. Please ensure jQuery is referenced before the SignalR.js file.";if(!t.JSON)throw"SignalR: No JSON parser found. Please ensure json2.js is referenced before the SignalR.js file if you need to support clients without native JSON parsing support, e.g. IE<8.";var i,f,r={onStart:"onStart",onStarting:"onStarting",onSending:"onSending",onReceived:"onReceived",onError:"onError",onReconnect:"onReconnect",onStateChanged:"onStateChanged",onDisconnect:"onDisconnect"},o=function(n,i){if(i!==!1){var r;typeof t.console!="undefined"&&(r="["+(new Date).toTimeString()+"] SignalR: "+n,t.console.debug?t.console.debug(r):t.console.log&&t.console.log(r))}},s=function(i){var r;return(i=n.trim(i),i.indexOf("http")!==0)?!1:(r=t.document.createElement("a"),r.href=i,r.protocol+r.host!==t.location.protocol+t.location.host)},u=function(t,i,u){return i===t.state?(n(t).trigger(r.onStateChanged,[{oldState:t.state,newState:u}]),t.state=u,!0):!1},e=function(n){return n.state===i.connectionState.disconnected};i=function(n,t,r){return new i.fn.init(n,t,r)},i.events=r,i.changeState=u,i.isDisconnecting=e,i.connectionState={connecting:0,connected:1,reconnecting:2,disconnected:4},i.hub={start:function(){throw"SignalR: Error loading hubs. Ensure your hubs reference is correct, e.g. <script src='/signalr/hubs'><\/script>.";}},i.fn=i.prototype={init:function(n,t,i){this.url=n,this.qs=t,typeof i=="boolean"&&(this.logging=i)},ajaxDataType:"json",logging:!1,state:i.connectionState.disconnected,reconnectDelay:2e3,start:function(f,e){var o=this,h={transport:"auto",jsonp:!1},a,l=n.Deferred(),c=t.document.createElement("a");return u(o,i.connectionState.disconnected,i.connectionState.connecting)===!1?(l.resolve(o),l.promise()):(n.type(f)==="function"?e=f:n.type(f)==="object"&&(n.extend(h,f),n.type(h.callback)==="function"&&(e=h.callback)),c.href=o.url,c.protocol&&c.protocol!==":"?(o.protocol=c.protocol,o.host=c.host,o.baseUrl=c.protocol+"//"+c.host):(o.protocol=t.document.location.protocol,o.host=t.document.location.host,o.baseUrl=o.protocol+"//"+o.host),o.wsProtocol=o.protocol==="https:"?"wss://":"ws://",s(o.url)&&(o.log("Auto detected cross domain url."),h.transport==="auto"&&(h.jsonp||(h.jsonp=!n.support.cors,h.jsonp&&o.log("Using jsonp because this browser doesn't support CORS")),h.transport=h.jsonp===!0?"longPolling":["webSockets","longPolling"])),o.ajaxDataType=h.jsonp?"jsonp":"json",n(o).bind(r.onStart,function(){n.type(e)==="function"&&e.call(o),l.resolve(o)}),a=function(f,e){if(e=e||0,e>=f.length){o.transport||l.reject("SignalR: No transport could be initialized successfully. Try specifying a different transport or none at all for auto initialization.");return}var s=f[e],h=n.type(s)==="object"?s:i.transports[s];if(s.indexOf("_")===0){a(f,e+1);return}h.start(o,function(){o.transport=h,u(o,i.connectionState.connecting,i.connectionState.connected),n(o).trigger(r.onStart),n(t).unload(function(){o.stop(!1)})},function(){a(f,e+1)})},t.setTimeout(function(){var t=o.url+"/negotiate";o.log("Negotiating with '"+t+"'."),n.ajax({url:t,global:!1,cache:!1,type:"GET",data:{},dataType:o.ajaxDataType,error:function(t){n(o).trigger(r.onError,[t.responseText]),l.reject("SignalR: Error during negotiation request: "+t.responseText),o.stop()},success:function(t){if(o.appRelativeUrl=t.Url,o.id=t.ConnectionId,o.webSocketServerUrl=t.WebSocketServerUrl,!t.ProtocolVersion||t.ProtocolVersion!=="1.0"){n(o).trigger(r.onError,"SignalR: Incompatible protocol version."),l.reject("SignalR: Incompatible protocol version.");return}n(o).trigger(r.onStarting);var f=[],u=[];n.each(i.transports,function(n){if(n==="webSockets"&&!t.TryWebSockets)return!0;u.push(n)}),n.isArray(h.transport)?n.each(h.transport,function(){var t=this;(n.type(t)==="object"||n.type(t)==="string"&&n.inArray(""+t,u)>=0)&&f.push(n.type(t)==="string"?""+t:t)}):n.type(h.transport)==="object"||n.inArray(h.transport,u)>=0?f.push(h.transport):f=u,a(f)}})},0),l.promise())},starting:function(t){var i=this,u=n(i);return u.bind(r.onStarting,function(){t.call(i),u.unbind(r.onStarting)}),i},send:function(n){var t=this;if(t.state===i.connectionState.disconnected)throw"SignalR: Connection must be started before data can be sent. Call .start() before .send()";if(t.state===i.connectionState.connecting)throw"SignalR: Connection has not been fully initialized. Use .start().done() or .start().fail() to run logic after the connection has started.";return t.transport.send(t,n),t},sending:function(t){var i=this;return n(i).bind(r.onSending,function(){t.call(i)}),i},received:function(t){var i=this;return n(i).bind(r.onReceived,function(n,r){t.call(i,r)}),i},stateChanged:function(t){var i=this;return n(i).bind(r.onStateChanged,function(n,r){t.call(i,r)}),i},error:function(t){var i=this;return n(i).bind(r.onError,function(n,r){t.call(i,r)}),i},disconnected:function(t){var i=this;return n(i).bind(r.onDisconnect,function(){t.call(i)}),i},reconnected:function(t){var i=this;return n(i).bind(r.onReconnect,function(){t.call(i)}),i},stop:function(t){var f=this;if(f.state!==i.connectionState.disconnected){try{f.transport&&(f.transport.abort(f,t),f.transport.stop(f),f.transport=null),n(f).trigger(r.onDisconnect),delete f.messageId,delete f.groups}finally{u(f,f.state,i.connectionState.disconnected)}return f}},log:function(n){o(n,this.logging)}},i.fn.init.prototype=i.fn,i.noConflict=function(){return n.connection===i&&(n.connection=f),i},n.connection&&(f=n.connection),n.connection=n.signalR=i})(window.jQuery,window),function(n,t){"use strict";var r=n.signalR,i=n.signalR.events;r.transports={},r.transports._logic={addQs:function(i,r){return r.qs?typeof r.qs=="object"?i+"&"+n.param(r.qs):typeof r.qs=="string"?i+"&"+r.qs:i+"&"+t.escape(r.qs.toString()):i},getUrl:function(n,i,r,u){var o=i==="webSockets"?"":n.baseUrl,f=o+n.appRelativeUrl,e="transport="+i+"&connectionId="+t.escape(n.id);return n.data&&(e+="&connectionData="+t.escape(n.data)),r?(u&&(f=f+"/reconnect"),n.messageId&&(e+="&messageId="+n.messageId),n.groups&&(e+="&groups="+t.escape(JSON.stringify(n.groups)))):f=f+"/connect",f+="?"+e,f=this.addQs(f,n),f+="&tid="+Math.floor(Math.random()*11)},ajaxSend:function(r,u){var f=r.url+"/send?transport="+r.transport.name+"&connectionId="+t.escape(r.id);return f=this.addQs(f,r),n.ajax({url:f,global:!1,type:"POST",dataType:r.ajaxDataType,data:{data:u},success:function(t){t&&n(r).trigger(i.onReceived,[t])},error:function(t,u){u!=="abort"&&(u!=="parsererror"||r.ajaxDataType!=="jsonp")&&n(r).trigger(i.onError,[t])}})},ajaxAbort:function(i,r){if(typeof i.transport!="undefined"){r=typeof r=="undefined"?!0:r;var u=i.url+"/abort?transport="+i.transport.name+"&connectionId="+t.escape(i.id);u=this.addQs(u,i),n.ajax({url:u,async:r,timeout:1e3,global:!1,type:"POST",dataType:i.ajaxDataType,data:{}}),i.log("Fired ajax abort async = "+r)}},processMessages:function(t,r){var u=n(t);if(r){if(r.Disconnect){t.log("Disconnect command received from server"),t.stop();return}r.Messages&&n.each(r.Messages,function(){try{u.trigger(i.onReceived,[this])}catch(r){t.log("Error raising received "+r),n(t).trigger(i.onError,[r])}}),r.MessageId&&(t.messageId=r.MessageId),r.TransportData&&(t.groups=r.TransportData.Groups)}},foreverFrame:{count:0,connections:{}}}}(window.jQuery,window),function(n,t){"use strict";var i=n.signalR,r=n.signalR.events,f=n.signalR.changeState,u=i.transports._logic;i.transports.webSockets={name:"webSockets",send:function(n,t){n.socket.send(t)},start:function(e,o,s){var h,a=!1,l=this,c=!o,v=n(e);if(t.MozWebSocket&&(t.WebSocket=t.MozWebSocket),!t.WebSocket){s();return}e.socket||(h=e.webSocketServerUrl?e.webSocketServerUrl:e.wsProtocol+e.host,n(e).trigger(r.onSending),h+=u.getUrl(e,this.name,c),e.log("Connecting to websocket endpoint '"+h+"'"),e.socket=new t.WebSocket(h),e.socket.onopen=function(){a=!0,e.log("Websocket opened"),o?o():f(e,i.connectionState.reconnecting,i.connectionState.connected)===!0&&v.trigger(r.onReconnect)},e.socket.onclose=function(t){if(a)typeof t.wasClean!="undefined"&&t.wasClean===!1?(n(e).trigger(r.onError,[t.reason]),e.log("Unclean disconnect from websocket."+t.reason)):e.log("Websocket closed");else{s?s():c&&l.reconnect(e);return}l.reconnect(e)},e.socket.onmessage=function(i){var f=t.JSON.parse(i.data),o;f&&(o=n(e),f.Messages?u.processMessages(e,f):o.trigger(r.onReceived,[f]))})},reconnect:function(n){var r=this;t.setTimeout(function(){r.stop(n),(n.state===i.connectionState.reconnecting||f(n,i.connectionState.connected,i.connectionState.reconnecting)===!0)&&(n.log("Websocket reconnecting"),r.start(n))},n.reconnectDelay)},stop:function(n){n.socket!==null&&(n.log("Closing the Websocket"),n.socket.close(),n.socket=null)},abort:function(){}}}(window.jQuery,window),function(n,t){"use strict";var i=n.signalR,u=n.signalR.events,f=n.signalR.changeState,r=i.transports._logic;i.transports.serverSentEvents={name:"serverSentEvents",timeOut:3e3,start:function(e,o,s){var c=this,a=!1,l=n(e),h=!o,y,v;if(e.eventSource&&(e.log("The connection already has an event source. Stopping it."),e.stop()),!t.EventSource){s&&(e.log("This browser doesn't support SSE."),s());return}l.trigger(u.onSending),y=r.getUrl(e,this.name,h);try{e.log("Attempting to connect to SSE endpoint '"+y+"'"),e.eventSource=new t.EventSource(y)}catch(p){e.log("EventSource failed trying to connect with error "+p.Message),s?s():(l.trigger(u.onError,[p]),h&&c.reconnect(e));return}v=t.setTimeout(function(){a===!1&&(e.log("EventSource timed out trying to connect"),e.log("EventSource readyState: "+e.eventSource.readyState),h||c.stop(e),h?e.eventSource.readyState!==t.EventSource.CONNECTING&&e.eventSource.readyState!==t.EventSource.OPEN&&c.reconnect(e):s&&s())},c.timeOut),e.eventSource.addEventListener("open",function(){e.log("EventSource connected"),v&&t.clearTimeout(v),a===!1&&(a=!0,o&&o(),h&&f(e,i.connectionState.reconnecting,i.connectionState.connected)===!0&&l.trigger(u.onReconnect))},!1),e.eventSource.addEventListener("message",function(n){n.data!=="initialized"&&r.processMessages(e,t.JSON.parse(n.data))},!1),e.eventSource.addEventListener("error",function(n){if(!a){s&&s();return}e.log("EventSource readyState: "+e.eventSource.readyState),n.eventPhase===t.EventSource.CLOSED?(e.log("EventSource reconnecting due to the server connection ending"),c.reconnect(e)):(e.log("EventSource error"),l.trigger(u.onError))},!1)},reconnect:function(n){var r=this;t.setTimeout(function(){r.stop(n),(n.state===i.connectionState.reconnecting||f(n,i.connectionState.connected,i.connectionState.reconnecting)===!0)&&(n.log("EventSource reconnecting"),r.start(n))},n.reconnectDelay)},send:function(n,t){r.ajaxSend(n,t)},stop:function(n){n&&n.eventSource&&(n.log("EventSource calling close()"),n.eventSource.close(),n.eventSource=null,delete n.eventSource)},abort:function(n,t){r.ajaxAbort(n,t)}}}(window.jQuery,window),function(n,t){"use strict";var r=n.signalR,u=n.signalR.events,f=n.signalR.changeState,i=r.transports._logic;r.transports.foreverFrame={name:"foreverFrame",timeOut:3e3,start:function(r,f,e){var s=this,h=i.foreverFrame.count+=1,c,l,o=n("<iframe data-signalr-connection-id='"+r.id+"' style='position:absolute;top:0;left:0;width:0;height:0;visibility:hidden;'></iframe>");if(t.EventSource){e&&(r.log("This brower supports SSE, skipping Forever Frame."),e());return}n(r).trigger(u.onSending),c=i.getUrl(r,this.name),c+="&frameId="+h,o.prop("src",c),i.foreverFrame.connections[h]=r,r.log("Binding to iframe's readystatechange event."),o.bind("readystatechange",function(){n.inArray(this.readyState,["loaded","complete"])>=0&&(r.log("Forever frame iframe readyState changed to "+this.readyState+", reconnecting"),s.reconnect(r))}),r.frame=o[0],r.frameId=h,f&&(r.onSuccess=f),n("body").append(o),l=t.setTimeout(function(){r.onSuccess&&(r.log("Failed to connect using forever frame source, it timed out after "+s.timeOut+"ms."),s.stop(r),e&&e())},s.timeOut)},reconnect:function(n){var u=this;t.setTimeout(function(){if(n.frame&&(n.state===r.connectionState.reconnecting||f(n,r.connectionState.connected,r.connectionState.reconnecting)===!0)){var e=n.frame,t=i.getUrl(n,u.name,!0)+"&frameId="+n.frameId;n.log("Upating iframe src to '"+t+"'."),e.src=t}},n.reconnectDelay)},send:function(n,t){i.ajaxSend(n,t)},receive:function(t,r){var u;i.processMessages(t,r),t.frameMessageCount=(t.frameMessageCount||0)+1,t.frameMessageCount>50&&(t.frameMessageCount=0,u=t.frame.contentWindow||t.frame.contentDocument,u&&u.document&&n("body",u.document).empty())},stop:function(t){var r=null;t.frame&&(t.frame.stop?t.frame.stop():(r=t.frame.contentWindow||t.frame.contentDocument,r.document&&r.document.execCommand&&r.document.execCommand("Stop")),n(t.frame).remove(),delete i.foreverFrame.connections[t.frameId],t.frame=null,t.frameId=null,delete t.frame,delete t.frameId,t.log("Stopping forever frame"))},abort:function(n,t){i.ajaxAbort(n,t)},getConnection:function(n){return i.foreverFrame.connections[n]},started:function(t){t.onSuccess?(t.onSuccess(),t.onSuccess=null,delete t.onSuccess):f(t,r.connectionState.reconnecting,r.connectionState.connected)===!0&&n(t).trigger(u.onReconnect)}}}(window.jQuery,window),function(n,t){"use strict";var i=n.signalR,u=n.signalR.events,f=n.signalR.changeState,e=n.signalR.isDisconnecting,r=i.transports._logic;i.transports.longPolling={name:"longPolling",reconnectDelay:3e3,start:function(o,s){var l=this,c=!1;o.pollXhr&&(o.log("Polling xhr requests already exists, aborting."),o.stop()),o.messageId=null,t.setTimeout(function(){(function h(a,v){n(a).trigger(u.onSending);var d=a.messageId,k=d===null,b=!k,w=r.getUrl(a,l.name,b,v),p=null,y=!1;(b!==!0||v!==!0||o.state===i.connectionState.reconnecting||f(o,i.connectionState.connected,i.connectionState.reconnecting)!==!1)&&(o.log("Attempting to connect to '"+w+"' using longPolling."),a.pollXhr=n.ajax({url:w,global:!1,cache:!1,type:"GET",dataType:o.ajaxDataType,success:function(l){var w=0,p=!1;(c===!1&&(s(),c=!0),v===!0&&y===!1&&(o.log("Raising the reconnect event"),f(o,i.connectionState.reconnecting,i.connectionState.connected)===!0&&(n(a).trigger(u.onReconnect),y=!0)),r.processMessages(a,l),l&&l.TransportData&&n.type(l.TransportData.LongPollDelay)==="number"&&(w=l.TransportData.LongPollDelay),l&&l.TimedOut&&(p=l.TimedOut),l&&l.Disconnect)||e(a)!==!0&&(w>0?t.setTimeout(function(){h(a,p)},w):h(a,p))},error:function(i,r){if(r==="abort"){o.log("Aborted xhr requst.");return}o.log("An error occurred using longPolling. Status = "+r+". "+i.responseText),p&&t.clearTimeout(p),n(a).trigger(u.onError,[i.responseText]),t.setTimeout(function(){e(a)===!1&&h(a,!0)},o.reconnectDelay)}}),v===!0&&(p=t.setTimeout(function(){y===!1&&f(o,i.connectionState.reconnecting,i.connectionState.connected)===!0&&(n(a).trigger(u.onReconnect),y=!0)},l.reconnectDelay)))})(o),t.setTimeout(function(){c===!1&&(s(),c=!0)},150)},250)},send:function(n,t){r.ajaxSend(n,t)},stop:function(n){n.pollXhr&&(n.pollXhr.abort(),n.pollXhr=null,delete n.pollXhr)},abort:function(n,t){r.ajaxAbort(n,t)}}}(window.jQuery,window)
+(function(n,t){"use strict";if(typeof n!="function")throw"SignalR: jQuery not found. Please ensure jQuery is referenced before the SignalR.js file.";if(!t.JSON)throw"SignalR: No JSON parser found. Please ensure json2.js is referenced before the SignalR.js file if you need to support clients without native JSON parsing support, e.g. IE<8.";var i,f,r={onStart:"onStart",onStarting:"onStarting",onSending:"onSending",onReceived:"onReceived",onError:"onError",onReconnect:"onReconnect",onStateChanged:"onStateChanged",onDisconnect:"onDisconnect"},o=function(n,i){if(i!==!1){var r;typeof t.console!="undefined"&&(r="["+(new Date).toTimeString()+"] SignalR: "+n,t.console.debug?t.console.debug(r):t.console.log&&t.console.log(r))}},s=function(i){var r;return(i=n.trim(i),i.indexOf("http")!==0)?!1:(r=t.document.createElement("a"),r.href=i,r.protocol+r.host!==t.location.protocol+t.location.host)},u=function(t,i,u){return i===t.state?(n(t).trigger(r.onStateChanged,[{oldState:t.state,newState:u}]),t.state=u,!0):!1},e=function(n){return n.state===i.connectionState.disconnected};i=function(n,t,r){return new i.fn.init(n,t,r)},i.events=r,i.changeState=u,i.isDisconnecting=e,i.connectionState={connecting:0,connected:1,reconnecting:2,disconnected:4},i.hub={start:function(){throw"SignalR: Error loading hubs. Ensure your hubs reference is correct, e.g. <script src='/signalr/hubs'><\/script>.";}},i.fn=i.prototype={init:function(n,t,i){this.url=n,this.qs=t,typeof i=="boolean"&&(this.logging=i)},ajaxDataType:"json",logging:!1,state:i.connectionState.disconnected,reconnectDelay:2e3,start:function(f,e){var o=this,h={transport:"auto",jsonp:!1},a,l=n.Deferred(),c=t.document.createElement("a");return u(o,i.connectionState.disconnected,i.connectionState.connecting)===!1?(l.resolve(o),l.promise()):(n.type(f)==="function"?e=f:n.type(f)==="object"&&(n.extend(h,f),n.type(h.callback)==="function"&&(e=h.callback)),c.href=o.url,c.protocol&&c.protocol!==":"?(o.protocol=c.protocol,o.host=c.host,o.baseUrl=c.protocol+"//"+c.host):(o.protocol=t.document.location.protocol,o.host=t.document.location.host,o.baseUrl=o.protocol+"//"+o.host),o.wsProtocol=o.protocol==="https:"?"wss://":"ws://",s(o.url)&&(o.log("Auto detected cross domain url."),h.transport==="auto"&&(h.jsonp||(h.jsonp=!n.support.cors,h.jsonp&&o.log("Using jsonp because this browser doesn't support CORS")),h.transport=h.jsonp===!0?"longPolling":["webSockets","longPolling"])),o.ajaxDataType=h.jsonp?"jsonp":"json",n(o).bind(r.onStart,function(){n.type(e)==="function"&&e.call(o),l.resolve(o)}),a=function(f,e){if(e=e||0,e>=f.length){o.transport||l.reject("SignalR: No transport could be initialized successfully. Try specifying a different transport or none at all for auto initialization.");return}var s=f[e],h=n.type(s)==="object"?s:i.transports[s];if(s.indexOf("_")===0){a(f,e+1);return}h.start(o,function(){o.transport=h,u(o,i.connectionState.connecting,i.connectionState.connected),n(o).trigger(r.onStart),n(t).unload(function(){o.stop(!1)})},function(){a(f,e+1)})},t.setTimeout(function(){var t=o.url+"/negotiate";o.log("Negotiating with '"+t+"'."),n.ajax({url:t,global:!1,cache:!1,type:"GET",data:{},dataType:o.ajaxDataType,error:function(t){n(o).trigger(r.onError,[t.responseText]),l.reject("SignalR: Error during negotiation request: "+t.responseText),o.stop()},success:function(t){if(o.appRelativeUrl=t.Url,o.id=t.ConnectionId,o.webSocketServerUrl=t.WebSocketServerUrl,!t.ProtocolVersion||t.ProtocolVersion!=="1.0"){n(o).trigger(r.onError,"SignalR: Incompatible protocol version."),l.reject("SignalR: Incompatible protocol version.");return}n(o).trigger(r.onStarting);var f=[],u=[];n.each(i.transports,function(n){if(n==="webSockets"&&!t.TryWebSockets)return!0;u.push(n)}),n.isArray(h.transport)?n.each(h.transport,function(){var t=this;(n.type(t)==="object"||n.type(t)==="string"&&n.inArray(""+t,u)>=0)&&f.push(n.type(t)==="string"?""+t:t)}):n.type(h.transport)==="object"||n.inArray(h.transport,u)>=0?f.push(h.transport):f=u,a(f)}})},0),l.promise())},starting:function(t){var i=this,u=n(i);return u.bind(r.onStarting,function(){t.call(i),u.unbind(r.onStarting)}),i},send:function(n){var t=this;if(t.state===i.connectionState.disconnected)throw"SignalR: Connection must be started before data can be sent. Call .start() before .send()";if(t.state===i.connectionState.connecting)throw"SignalR: Connection has not been fully initialized. Use .start().done() or .start().fail() to run logic after the connection has started.";return t.transport.send(t,n),t},sending:function(t){var i=this;return n(i).bind(r.onSending,function(){t.call(i)}),i},received:function(t){var i=this;return n(i).bind(r.onReceived,function(n,r){t.call(i,r)}),i},stateChanged:function(t){var i=this;return n(i).bind(r.onStateChanged,function(n,r){t.call(i,r)}),i},error:function(t){var i=this;return n(i).bind(r.onError,function(n,r){t.call(i,r)}),i},disconnected:function(t){var i=this;return n(i).bind(r.onDisconnect,function(){t.call(i)}),i},reconnected:function(t){var i=this;return n(i).bind(r.onReconnect,function(){t.call(i)}),i},stop:function(t){var f=this;if(f.state!==i.connectionState.disconnected){try{f.transport&&(f.transport.abort(f,t),f.transport.stop(f),f.transport=null),n(f).trigger(r.onDisconnect),delete f.messageId,delete f.groups}finally{u(f,f.state,i.connectionState.disconnected)}return f}},log:function(n){o(n,this.logging)}},i.fn.init.prototype=i.fn,i.noConflict=function(){return n.connection===i&&(n.connection=f),i},n.connection&&(f=n.connection),n.connection=n.signalR=i})(window.jQuery,window),function(n,t){"use strict";var r=n.signalR,i=n.signalR.events;r.transports={},r.transports._logic={addQs:function(i,r){return r.qs?typeof r.qs=="object"?i+"&"+n.param(r.qs):typeof r.qs=="string"?i+"&"+r.qs:i+"&"+t.escape(r.qs.toString()):i},getUrl:function(n,i,r,u){var o=i==="webSockets"?"":n.baseUrl,f=o+n.appRelativeUrl,e="transport="+i+"&connectionId="+t.escape(n.id);return n.data&&(e+="&connectionData="+t.escape(n.data)),r?(u&&(f=f+"/reconnect"),n.messageId&&(e+="&messageId="+n.messageId),n.groups&&(e+="&groups="+t.escape(JSON.stringify(n.groups)))):f=f+"/connect",f+="?"+e,f=this.addQs(f,n),f+="&tid="+Math.floor(Math.random()*11)},ajaxSend:function(r,u){var f=r.url+"/send?transport="+r.transport.name+"&connectionId="+t.escape(r.id);return f=this.addQs(f,r),n.ajax({url:f,global:!1,type:"POST",dataType:r.ajaxDataType,data:{data:u},success:function(t){t&&n(r).trigger(i.onReceived,[t])},error:function(t,u){u!=="abort"&&(u!=="parsererror"||r.ajaxDataType!=="jsonp")&&n(r).trigger(i.onError,[t])}})},ajaxAbort:function(i,r){if(typeof i.transport!="undefined"){r=typeof r=="undefined"?!0:r;var u=i.url+"/abort?transport="+i.transport.name+"&connectionId="+t.escape(i.id);u=this.addQs(u,i),n.ajax({url:u,async:r,timeout:1e3,global:!1,type:"POST",dataType:i.ajaxDataType,data:{}}),i.log("Fired ajax abort async = "+r)}},processMessages:function(t,r){var u=n(t);if(r){if(r.Disconnect){t.log("Disconnect command received from server"),t.stop();return}r.Messages&&n.each(r.Messages,function(){try{u.trigger(i.onReceived,[this])}catch(r){t.log("Error raising received "+r),n(t).trigger(i.onError,[r])}}),r.MessageId&&(t.messageId=r.MessageId),r.TransportData&&(t.groups=r.TransportData.Groups)}},foreverFrame:{count:0,connections:{}}}}(window.jQuery,window),function(n,t){"use strict";var i=n.signalR,r=n.signalR.events,f=n.signalR.changeState,u=i.transports._logic;i.transports.webSockets={name:"webSockets",send:function(n,t){n.socket.send(t)},start:function(e,o,s){var h,a=!1,l=this,c=!o,v=n(e);if(t.MozWebSocket&&(t.WebSocket=t.MozWebSocket),!t.WebSocket){s();return}e.socket||(h=e.webSocketServerUrl?e.webSocketServerUrl:e.wsProtocol+e.host,n(e).trigger(r.onSending),h+=u.getUrl(e,this.name,c),e.log("Connecting to websocket endpoint '"+h+"'"),e.socket=new t.WebSocket(h),e.socket.onopen=function(){a=!0,e.log("Websocket opened"),o?o():f(e,i.connectionState.reconnecting,i.connectionState.connected)===!0&&v.trigger(r.onReconnect)},e.socket.onclose=function(t){if(a)typeof t.wasClean!="undefined"&&t.wasClean===!1?(n(e).trigger(r.onError,[t.reason]),e.log("Unclean disconnect from websocket."+t.reason)):e.log("Websocket closed");else{s?s():c&&l.reconnect(e);return}l.reconnect(e)},e.socket.onmessage=function(i){var f=t.JSON.parse(i.data),o;f&&(o=n(e),f.Messages?u.processMessages(e,f):o.trigger(r.onReceived,[f]))})},reconnect:function(n){var r=this;t.setTimeout(function(){r.stop(n),(n.state===i.connectionState.reconnecting||f(n,i.connectionState.connected,i.connectionState.reconnecting)===!0)&&(n.log("Websocket reconnecting"),r.start(n))},n.reconnectDelay)},stop:function(n){n.socket!==null&&(n.log("Closing the Websocket"),n.socket.close(),n.socket=null)},abort:function(){}}}(window.jQuery,window),function(n,t){"use strict";var i=n.signalR,u=n.signalR.events,f=n.signalR.changeState,r=i.transports._logic;i.transports.serverSentEvents={name:"serverSentEvents",timeOut:3e3,start:function(e,o,s){var c=this,a=!1,l=n(e),h=!o,y,v;if(e.eventSource&&(e.log("The connection already has an event source. Stopping it."),e.stop()),!t.EventSource){s&&(e.log("This browser doesn't support SSE."),s());return}l.trigger(u.onSending),y=r.getUrl(e,this.name,h);try{e.log("Attempting to connect to SSE endpoint '"+y+"'"),e.eventSource=new t.EventSource(y)}catch(p){e.log("EventSource failed trying to connect with error "+p.Message),s?s():(l.trigger(u.onError,[p]),h&&c.reconnect(e));return}v=t.setTimeout(function(){a===!1&&(e.log("EventSource timed out trying to connect"),e.log("EventSource readyState: "+e.eventSource.readyState),h||c.stop(e),h?e.eventSource.readyState!==t.EventSource.CONNECTING&&e.eventSource.readyState!==t.EventSource.OPEN&&c.reconnect(e):s&&s())},c.timeOut),e.eventSource.addEventListener("open",function(){e.log("EventSource connected"),v&&t.clearTimeout(v),a===!1&&(a=!0,o&&o(),h&&f(e,i.connectionState.reconnecting,i.connectionState.connected)===!0&&l.trigger(u.onReconnect))},!1),e.eventSource.addEventListener("message",function(n){n.data!=="initialized"&&r.processMessages(e,t.JSON.parse(n.data))},!1),e.eventSource.addEventListener("error",function(n){if(!a){s&&s();return}e.log("EventSource readyState: "+e.eventSource.readyState),n.eventPhase===t.EventSource.CLOSED?(e.log("EventSource reconnecting due to the server connection ending"),c.reconnect(e)):(e.log("EventSource error"),l.trigger(u.onError))},!1)},reconnect:function(n){var r=this;t.setTimeout(function(){r.stop(n),(n.state===i.connectionState.reconnecting||f(n,i.connectionState.connected,i.connectionState.reconnecting)===!0)&&(n.log("EventSource reconnecting"),r.start(n))},n.reconnectDelay)},send:function(n,t){r.ajaxSend(n,t)},stop:function(n){n&&n.eventSource&&(n.log("EventSource calling close()"),n.eventSource.close(),n.eventSource=null,delete n.eventSource)},abort:function(n,t){r.ajaxAbort(n,t)}}}(window.jQuery,window),function(n,t){"use strict";var r=n.signalR,u=n.signalR.events,f=n.signalR.changeState,i=r.transports._logic;r.transports.foreverFrame={name:"foreverFrame",timeOut:3e3,start:function(r,f,e){var s=this,h=i.foreverFrame.count+=1,c,l,o=n("<iframe data-signalr-connection-id='"+r.id+"' style='position:absolute;top:0;left:0;width:0;height:0;visibility:hidden;'></iframe>");if(t.EventSource){e&&(r.log("This brower supports SSE, skipping Forever Frame."),e());return}n(r).trigger(u.onSending),c=i.getUrl(r,this.name),c+="&frameId="+h,o.prop("src",c),i.foreverFrame.connections[h]=r,r.log("Binding to iframe's readystatechange event."),o.bind("readystatechange",function(){n.inArray(this.readyState,["loaded","complete"])>=0&&(r.log("Forever frame iframe readyState changed to "+this.readyState+", reconnecting"),s.reconnect(r))}),r.frame=o[0],r.frameId=h,f&&(r.onSuccess=f),n("body").append(o),l=t.setTimeout(function(){r.onSuccess&&(r.log("Failed to connect using forever frame source, it timed out after "+s.timeOut+"ms."),s.stop(r),e&&e())},s.timeOut)},reconnect:function(n){var u=this;t.setTimeout(function(){if(n.frame&&(n.state===r.connectionState.reconnecting||f(n,r.connectionState.connected,r.connectionState.reconnecting)===!0)){var e=n.frame,t=i.getUrl(n,u.name,!0)+"&frameId="+n.frameId;n.log("Upating iframe src to '"+t+"'."),e.src=t}},n.reconnectDelay)},send:function(n,t){i.ajaxSend(n,t)},receive:function(t,r){var u;i.processMessages(t,r),t.frameMessageCount=(t.frameMessageCount||0)+1,t.frameMessageCount>50&&(t.frameMessageCount=0,u=t.frame.contentWindow||t.frame.contentDocument,u&&u.document&&n("body",u.document).empty())},stop:function(t){var r=null;t.frame&&(t.frame.stop?t.frame.stop():(r=t.frame.contentWindow||t.frame.contentDocument,r.document&&r.document.execCommand&&r.document.execCommand("Stop")),n(t.frame).remove(),delete i.foreverFrame.connections[t.frameId],t.frame=null,t.frameId=null,delete t.frame,delete t.frameId,t.log("Stopping forever frame"))},abort:function(n,t){i.ajaxAbort(n,t)},getConnection:function(n){return i.foreverFrame.connections[n]},started:function(t){t.onSuccess?(t.onSuccess(),t.onSuccess=null,delete t.onSuccess):f(t,r.connectionState.reconnecting,r.connectionState.connected)===!0&&n(t).trigger(u.onReconnect)}}}(window.jQuery,window),function(n,t){"use strict";var i=n.signalR,u=n.signalR.events,f=n.signalR.changeState,e=n.signalR.isDisconnecting,r=i.transports._logic;i.transports.longPolling={name:"longPolling",reconnectDelay:3e3,start:function(o,s){var l=this,c=!1;o.pollXhr&&(o.log("Polling xhr requests already exists, aborting."),o.stop()),o.messageId=null,t.setTimeout(function(){(function h(a,v){n(a).trigger(u.onSending);var d=a.messageId,k=d===null,b=!k,w=r.getUrl(a,l.name,b,v),p=null,y=!1;(b!==!0||v!==!0||o.state===i.connectionState.reconnecting||f(o,i.connectionState.connected,i.connectionState.reconnecting)!==!1)&&(o.log("Attempting to connect to '"+w+"' using longPolling."),a.pollXhr=n.ajax({url:w,global:!1,cache:!1,type:"GET",dataType:o.ajaxDataType,success:function(l){var w=0,p=!1;(c===!1&&(s(),c=!0),v===!0&&y===!1&&(o.log("Raising the reconnect event"),f(o,i.connectionState.reconnecting,i.connectionState.connected)===!0&&(n(a).trigger(u.onReconnect),y=!0)),r.processMessages(a,l),l&&l.TransportData&&n.type(l.TransportData.LongPollDelay)==="number"&&(w=l.TransportData.LongPollDelay),l&&l.TimedOut&&(p=l.TimedOut),l&&l.Disconnect)||e(a)!==!0&&(w>0?t.setTimeout(function(){h(a,p)},w):h(a,p))},error:function(i,r){if(r==="abort"){o.log("Aborted xhr requst.");return}o.log("An error occurred using longPolling. Status = "+r+". "+i.responseText),p&&t.clearTimeout(p),n(a).trigger(u.onError,[i.responseText]),t.setTimeout(function(){e(a)===!1&&h(a,!0)},o.reconnectDelay)}}),v===!0&&(p=t.setTimeout(function(){y===!1&&f(o,i.connectionState.reconnecting,i.connectionState.connected)===!0&&(n(a).trigger(u.onReconnect),y=!0)},l.reconnectDelay)))})(o),t.setTimeout(function(){c===!1&&(s(),c=!0)},150)},250)},send:function(n,t){r.ajaxSend(n,t)},stop:function(n){n.pollXhr&&(n.pollXhr.abort(),n.pollXhr=null,delete n.pollXhr)},abort:function(n,t){r.ajaxAbort(n,t)}}}(window.jQuery,window),function(n,t){"use strict";function e(t){return n.isFunction(t)?null:n.type(t)==="undefined"?null:t}function r(n,t){return new r.fn.init(n,t)}function i(n){return n||(n="/signalr"),new i.fn.init(n)}var f=0,u={};Array.prototype.hasOwnProperty("map")||(Array.prototype.map=function(n,t){for(var r=this,f=r.length,u=[],i=0;i<f;i+=1)r.hasOwnProperty(i)&&(u[i]=n.call(t,r[i],i,r));return u}),r.fn=r.prototype={init:function(n,t){this.state={},this.connection=n,this.hubName=t},on:function(t,i){var r=this;return n(r).bind(t,function(n,t){i.apply(r,t)}),r},invoke:function(i){var r=this,o=n.makeArray(arguments).slice(1),h=o[o.length-1],a=n.type(h)==="function"?o.slice(0,-1):o,v=a.map(e),l={hub:r.hubName,method:i,args:v,state:r.state,id:f},s=n.Deferred(),c=function(t){n.extend(this.state,t.State),t.Error?(t.StackTrace&&r.connection.log(t.Error+"\n"+t.StackTrace),s.rejectWith(r,[t.Error])):(n.type(h)==="function"&&h.call(r,t.Result),s.resolveWith(r,[t.Result]))};return u[f.toString()]={scope:r,method:c},f+=1,r.connection.send(t.JSON.stringify(l)),s.promise()}},r.fn.init.prototype=r.fn,i.fn=i.prototype=n.connection(),i.fn.init=function(i,r,f){var e=this;n.signalR.fn.init.call(e,i,r,f),e.proxies={},e.sending(function(){var i=[];n.each(this.proxies,function(n){i.push({name:n})}),this.data=t.JSON.stringify(i)}),e.received(function(t){var f,i,r;t&&(typeof t.Id!="undefined"?(i=t.Id.toString(),r=u[i],r&&(u[i]=null,delete u[i],r.method.call(r.scope,t))):(f=this.proxies[t.Hub],n.extend(f.state,t.State),n(f).trigger(t.Method,[t.Args])))})},i.fn.createProxy=function(n){var t=this.proxies[n];return t||(t=r(this,n),this.proxies[n]=t),t},i.fn.init.prototype=i.fn,n.hubConnection=i}(window.jQuery,window)
View
1,274 samples/SignalR.Hosting.Owin.Samples/Content/Scripts/jquery.signalR.js
@@ -1,27 +1,28 @@
+/* jquery.signalR.core.js */
+/*global window:false */
/*!
-* SignalR JavaScript Library v0.5.2
-* http://signalr.net/
-*
-* Copyright David Fowler and Damian Edwards 2012
-* Licensed under the MIT.
-* https://github.com/SignalR/SignalR/blob/master/LICENSE.md
-*/
-
-/// <reference path="jquery-1.6.2.js" />
+ * SignalR JavaScript Library v0.5.2
+ * http://signalr.net/
+ *
+ * Copyright David Fowler and Damian Edwards 2012
+ * Licensed under the MIT.
+ * https://github.com/SignalR/SignalR/blob/master/LICENSE.md
+ */
+
+/// <reference path="Scripts/jquery-1.6.2.js" />
(function ($, window) {
- /// <param name="$" type="jQuery" />
"use strict";
-
+
if (typeof ($) !== "function") {
// no jQuery!
throw "SignalR: jQuery not found. Please ensure jQuery is referenced before the SignalR.js file.";
}
-
+
if (!window.JSON) {
// no JSON!
throw "SignalR: No JSON parser found. Please ensure json2.js is referenced before the SignalR.js file if you need to support clients without native JSON parsing support, e.g. IE<8.";
}
-
+
var signalR,
_connection,
@@ -94,10 +95,15 @@
/// [Optional] A flag indicating whether connection logging is enabled to the browser
/// console/log. Defaults to false.
/// </param>
- /// <returns type="signalR" />
return new signalR.fn.init(url, qs, logging);
};
+
+ signalR.events = events;
+
+ signalR.changeState = changeState;
+
+ signalR.isDisconnecting = isDisconnecting;
signalR.connectionState = {
connecting: 0,
@@ -105,6 +111,13 @@
reconnecting: 2,
disconnected: 4
};
+
+ signalR.hub = {
+ start: function () {
+ // This will get replaced with the real hub connection start method when hubs is referenced correctly
+ throw "SignalR: Error loading hubs. Ensure your hubs reference is correct, e.g. <script src='/signalr/hubs'></script>.";
+ }
+ };
signalR.fn = signalR.prototype = {
init: function (url, qs, logging) {
@@ -218,6 +231,12 @@
var transportName = transports[index],
transport = $.type(transportName) === "object" ? transportName : signalR.transports[transportName];
+ if (transportName.indexOf("_") === 0) {
+ // Private member
+ initialize(transports, index + 1);
+ return;
+ }
+
transport.start(connection, function () { // success
connection.transport = transport;
@@ -284,8 +303,7 @@
transports.push($.type(transport) === "string" ? "" + transport : transport);
}
});
- } else if ($.type(config.transport) === "object" ||
- $.inArray(config.transport, supportedTransports) >= 0) {
+ } else if ($.type(config.transport) === "object" || $.inArray(config.transport, supportedTransports) >= 0) {
// specific transport provided, as object or a named transport, e.g. "longPolling"
transports.push(config.transport);
} else { // default "auto"
@@ -438,10 +456,35 @@
signalR.fn.init.prototype = signalR.fn;
+ signalR.noConflict = function () {
+ /// <summary>Reinstates the original value of $.connection and returns the signalR object for manual assignment</summary>
+ /// <returns type="signalR" />
+ if ($.connection === signalR) {
+ $.connection = _connection;
+ }
+ return signalR;
+ };
+
+ if ($.connection) {
+ _connection = $.connection;
+ }
+
+ $.connection = $.signalR = signalR;
+
+}(window.jQuery, window));
+/* jquery.signalR.transports.common.js */
+/*global window:false */
+/// <reference path="jquery.signalR.core.js" />
+
+(function ($, window) {
+ "use strict";
+
+ var signalR = $.signalR,
+ events = $.signalR.events;
- // Transports
- var transportLogic = {
+ signalR.transports = {};
+ signalR.transports._logic = {
addQs: function (url, connection) {
if (!connection.qs) {
return url;
@@ -490,7 +533,7 @@
ajaxSend: function (connection, data) {
var url = connection.url + "/send" + "?transport=" + connection.transport.name + "&connectionId=" + window.escape(connection.id);
url = this.addQs(url, connection);
- $.ajax({
+ return $.ajax({
url: url,
global: false,
type: "POST",
@@ -581,628 +624,841 @@
}
};
- signalR.transports = {
+}(window.jQuery, window));
+/* jquery.signalR.transports.webSockets.js */
+/*global window:false */
+/// <reference path="jquery.signalR.transports.common.js" />
- webSockets: {
- name: "webSockets",
+(function ($, window) {
+ "use strict";
- send: function (connection, data) {
- connection.socket.send(data);
- },
+ var signalR = $.signalR,
+ events = $.signalR.events,
+ changeState = $.signalR.changeState,
+ transportLogic = signalR.transports._logic;
- start: function (connection, onSuccess, onFailed) {
- var url,
- opened = false,
- that = this,
- reconnecting = !onSuccess,
- protocol,
- $connection = $(connection);
+ signalR.transports.webSockets = {
+ name: "webSockets",
- if (window.MozWebSocket) {
- window.WebSocket = window.MozWebSocket;
- }
+ send: function (connection, data) {
+ connection.socket.send(data);
+ },
- if (!window.WebSocket) {
- onFailed();
- return;
+ start: function (connection, onSuccess, onFailed) {
+ var url,
+ opened = false,
+ that = this,
+ reconnecting = !onSuccess,
+ $connection = $(connection);
+
+ if (window.MozWebSocket) {
+ window.WebSocket = window.MozWebSocket;
+ }
+
+ if (!window.WebSocket) {
+ onFailed();
+ return;
+ }
+
+ if (!connection.socket) {
+ if (connection.webSocketServerUrl) {
+ url = connection.webSocketServerUrl;
}
+ else {
+ url = connection.wsProtocol + connection.host;
+ }
+
+ // Build the url
+ $(connection).trigger(events.onSending);
+
+ url += transportLogic.getUrl(connection, this.name, reconnecting);
- if (!connection.socket) {
- if (connection.webSocketServerUrl) {
- url = connection.webSocketServerUrl;
+ connection.log("Connecting to websocket endpoint '" + url + "'");
+ connection.socket = new window.WebSocket(url);
+ connection.socket.onopen = function () {
+ opened = true;
+ connection.log("Websocket opened");
+ if (onSuccess) {
+ onSuccess();
}
else {
- url = connection.wsProtocol + connection.host;
+ if (changeState(connection,
+ signalR.connectionState.reconnecting,
+ signalR.connectionState.connected) === true) {
+ $connection.trigger(events.onReconnect);
+ }
}
+ };
- // Build the url
- $(connection).trigger(events.onSending);
-
- url += transportLogic.getUrl(connection, this.name, reconnecting);
-
- connection.log("Connecting to websocket endpoint '" + url + "'");
- connection.socket = new window.WebSocket(url);
- connection.socket.onopen = function () {
- opened = true;
- connection.log("Websocket opened");
- if (onSuccess) {
- onSuccess();
- }
- else {
- if (changeState(connection,
- signalR.connectionState.reconnecting,
- signalR.connectionState.connected) === true) {
- $connection.trigger(events.onReconnect);
- }
+ connection.socket.onclose = function (event) {
+ if (!opened) {
+ if (onFailed) {
+ onFailed();
}
- };
-
- connection.socket.onclose = function (event) {
- if (!opened) {
- if (onFailed) {
- onFailed();
- }
- else if(reconnecting) {
- that.reconnect(connection);
- }
- return;
+ else if (reconnecting) {
+ that.reconnect(connection);
}
- else if (typeof event.wasClean !== "undefined" && event.wasClean === false) {
+ return;
+ }
+ else if (typeof event.wasClean !== "undefined" && event.wasClean === false) {
// Ideally this would use the websocket.onerror handler (rather than checking wasClean in onclose) but
// I found in some circumstances Chrome won't call onerror. This implementation seems to work on all browsers.
- $(connection).trigger(events.onError, [event.reason]);
- connection.log("Unclean disconnect from websocket." + event.reason);
- }
- else {
- connection.log("Websocket closed");
- }
+ $(connection).trigger(events.onError, [event.reason]);
+ connection.log("Unclean disconnect from websocket." + event.reason);
+ }
+ else {
+ connection.log("Websocket closed");
+ }
- that.reconnect(connection);
- };
+ that.reconnect(connection);
+ };
- connection.socket.onmessage = function (event) {
- var data = window.JSON.parse(event.data),
- $connection;
- if (data) {
- $connection = $(connection);
+ connection.socket.onmessage = function (event) {
+ var data = window.JSON.parse(event.data),
+ $connection;
+ if (data) {
+ $connection = $(connection);
- if (data.Messages) {
- transportLogic.processMessages(connection, data);
- } else {
- $connection.trigger(events.onReceived, [data]);
- }
+ if (data.Messages) {
+ transportLogic.processMessages(connection, data);
+ } else {
+ $connection.trigger(events.onReceived, [data]);
}
- };
- }
- },
-
- reconnect: function (connection) {
- var that = this;
- window.setTimeout(function () {
- that.stop(connection);
+ }
+ };
+ }
+ },
- if (connection.state === signalR.connectionState.reconnecting ||
- changeState(connection,
- signalR.connectionState.connected,
- signalR.connectionState.reconnecting) === true) {
+ reconnect: function (connection) {
+ var that = this;
+ window.setTimeout(function () {
+ that.stop(connection);
- connection.log("Websocket reconnecting");
- that.start(connection);
- }
- },
- connection.reconnectDelay);
- },
+ if (connection.state === signalR.connectionState.reconnecting ||
+ changeState(connection,
+ signalR.connectionState.connected,
+ signalR.connectionState.reconnecting) === true) {
- stop: function (connection) {
- if (connection.socket !== null) {
- connection.log("Closing the Websocket");
- connection.socket.close();
- connection.socket = null;
+ connection.log("Websocket reconnecting");
+ that.start(connection);
}
},
+ connection.reconnectDelay);
+ },
- abort: function (connection) {
+ stop: function (connection) {
+ if (connection.socket !== null) {
+ connection.log("Closing the Websocket");
+ connection.socket.close();
+ connection.socket = null;
}
},
- serverSentEvents: {
- name: "serverSentEvents",
+ abort: function (connection) {
+ }
+ };
- timeOut: 3000,
+}(window.jQuery, window));
+/* jquery.signalR.transports.serverSentEvents.js */
+/*global window:false */
+/// <reference path="jquery.signalR.transports.common.js" />
- start: function (connection, onSuccess, onFailed) {
- var that = this,
- opened = false,
- $connection = $(connection),
- reconnecting = !onSuccess,
- url,
- connectTimeOut;
+(function ($, window) {
+ "use strict";
- if (connection.eventSource) {
- connection.log("The connection already has an event source. Stopping it.");
- connection.stop();
- }
+ var signalR = $.signalR,
+ events = $.signalR.events,
+ changeState = $.signalR.changeState,
+ transportLogic = signalR.transports._logic;
- if (!window.EventSource) {
- if (onFailed) {
- connection.log("This browser doesn't support SSE.");
- onFailed();
- }
- return;
+ signalR.transports.serverSentEvents = {
+ name: "serverSentEvents",
+
+ timeOut: 3000,
+
+ start: function (connection, onSuccess, onFailed) {
+ var that = this,
+ opened = false,
+ $connection = $(connection),
+ reconnecting = !onSuccess,
+ url,
+ connectTimeOut;
+
+ if (connection.eventSource) {
+ connection.log("The connection already has an event source. Stopping it.");
+ connection.stop();
+ }
+
+ if (!window.EventSource) {
+ if (onFailed) {
+ connection.log("This browser doesn't support SSE.");
+ onFailed();
}
+ return;
+ }
- $connection.trigger(events.onSending);
+ $connection.trigger(events.onSending);
- url = transportLogic.getUrl(connection, this.name, reconnecting);
+ url = transportLogic.getUrl(connection, this.name, reconnecting);
- try {
- connection.log("Attempting to connect to SSE endpoint '" + url + "'");
- connection.eventSource = new window.EventSource(url);
+ try {
+ connection.log("Attempting to connect to SSE endpoint '" + url + "'");
+ connection.eventSource = new window.EventSource(url);
+ }
+ catch (e) {
+ connection.log("EventSource failed trying to connect with error " + e.Message);
+ if (onFailed) {
+ // The connection failed, call the failed callback
+ onFailed();
}
- catch (e) {
- connection.log("EventSource failed trying to connect with error " + e.Message);
- if (onFailed) {
- // The connection failed, call the failed callback
- onFailed();
- }
- else {
- $connection.trigger(events.onError, [e]);
- if (reconnecting) {
- // If we were reconnecting, rather than doing initial connect, then try reconnect again
- that.reconnect(connection);
- }
+ else {
+ $connection.trigger(events.onError, [e]);
+ if (reconnecting) {
+ // If we were reconnecting, rather than doing initial connect, then try reconnect again
+ that.reconnect(connection);
}
- return;
}
+ return;
+ }
- // After connecting, if after the specified timeout there's no response stop the connection
- // and raise on failed
- connectTimeOut = window.setTimeout(function () {
- if (opened === false) {
- connection.log("EventSource timed out trying to connect");
- connection.log("EventSource readyState: " + connection.eventSource.readyState);
-
- if (!reconnecting) {
- that.stop(connection);
- }
+ // After connecting, if after the specified timeout there's no response stop the connection
+ // and raise on failed
+ connectTimeOut = window.setTimeout(function () {
+ if (opened === false) {
+ connection.log("EventSource timed out trying to connect");
+ connection.log("EventSource readyState: " + connection.eventSource.readyState);
- if (reconnecting) {
- // If we're reconnecting and the event source is attempting to connect,
- // don't keep retrying. This causes duplicate connections to spawn.
- if (connection.eventSource.readyState !== window.EventSource.CONNECTING &&
- connection.eventSource.readyState !== window.EventSource.OPEN) {
- // If we were reconnecting, rather than doing initial connect, then try reconnect again
- that.reconnect(connection);
- }
- } else if (onFailed) {
- onFailed();
- }
+ if (!reconnecting) {
+ that.stop(connection);
}
- },
- that.timeOut);
- connection.eventSource.addEventListener("open", function (e) {
- connection.log("EventSource connected");
-
- if (connectTimeOut) {
- window.clearTimeout(connectTimeOut);
+ if (reconnecting) {
+ // If we're reconnecting and the event source is attempting to connect,
+ // don't keep retrying. This causes duplicate connections to spawn.
+ if (connection.eventSource.readyState !== window.EventSource.CONNECTING &&
+ connection.eventSource.readyState !== window.EventSource.OPEN) {
+ // If we were reconnecting, rather than doing initial connect, then try reconnect again
+ that.reconnect(connection);
+ }
+ } else if (onFailed) {
+ onFailed();
}
+ }
+ },
+ that.timeOut);
- if (opened === false) {
- opened = true;
+ connection.eventSource.addEventListener("open", function (e) {
+ connection.log("EventSource connected");
- if (onSuccess) {
- onSuccess();
- }
+ if (connectTimeOut) {
+ window.clearTimeout(connectTimeOut);
+ }
- if (reconnecting) {
- if (changeState(connection,
- signalR.connectionState.reconnecting,
- signalR.connectionState.connected) === true) {
- $connection.trigger(events.onReconnect);
- }
- }
- }
- }, false);
+ if (opened === false) {
+ opened = true;
- connection.eventSource.addEventListener("message", function (e) {
- // process messages
- if (e.data === "initialized") {
- return;
+ if (onSuccess) {
+ onSuccess();
}
- transportLogic.processMessages(connection, window.JSON.parse(e.data));
- }, false);
- connection.eventSource.addEventListener("error", function (e) {
- if (!opened) {
- if (onFailed) {
- onFailed();
+ if (reconnecting) {
+ if (changeState(connection,
+ signalR.connectionState.reconnecting,
+ signalR.connectionState.connected) === true) {
+ $connection.trigger(events.onReconnect);
}
- return;
}
+ }
+ }, false);
- connection.log("EventSource readyState: " + connection.eventSource.readyState);
+ connection.eventSource.addEventListener("message", function (e) {
+ // process messages
+ if (e.data === "initialized") {
+ return;
+ }
+ transportLogic.processMessages(connection, window.JSON.parse(e.data));
+ }, false);
- if (e.eventPhase === window.EventSource.CLOSED) {
- // We don't use the EventSource's native reconnect function as it
- // doesn't allow us to change the URL when reconnecting. We need
- // to change the URL to not include the /connect suffix, and pass
- // the last message id we received.
- connection.log("EventSource reconnecting due to the server connection ending");
- that.reconnect(connection);
- } else {
- // connection error
- connection.log("EventSource error");
- $connection.trigger(events.onError);
+ connection.eventSource.addEventListener("error", function (e) {
+ if (!opened) {
+ if (onFailed) {
+ onFailed();
}
- }, false);
- },
+ return;
+ }
- reconnect: function (connection) {
- var that = this;
- window.setTimeout(function () {
- that.stop(connection);
+ connection.log("EventSource readyState: " + connection.eventSource.readyState);
+
+ if (e.eventPhase === window.EventSource.CLOSED) {
+ // We don't use the EventSource's native reconnect function as it
+ // doesn't allow us to change the URL when reconnecting. We need
+ // to change the URL to not include the /connect suffix, and pass
+ // the last message id we received.
+ connection.log("EventSource reconnecting due to the server connection ending");
+ that.reconnect(connection);
+ } else {
+ // connection error
+ connection.log("EventSource error");
+ $connection.trigger(events.onError);
+ }
+ }, false);
+ },
- if (connection.state === signalR.connectionState.reconnecting ||
- changeState(connection,
- signalR.connectionState.connected,
- signalR.connectionState.reconnecting) === true) {
- connection.log("EventSource reconnecting");
- that.start(connection);
- }
+ reconnect: function (connection) {
+ var that = this;
+ window.setTimeout(function () {
+ that.stop(connection);
- }, connection.reconnectDelay);
- },
+ if (connection.state === signalR.connectionState.reconnecting ||
+ changeState(connection,
+ signalR.connectionState.connected,
+ signalR.connectionState.reconnecting) === true) {
+ connection.log("EventSource reconnecting");
+ that.start(connection);
+ }
- send: function (connection, data) {
- transportLogic.ajaxSend(connection, data);
- },
+ }, connection.reconnectDelay);
+ },
- stop: function (connection) {
- if (connection && connection.eventSource) {
- connection.log("EventSource calling close()");
- connection.eventSource.close();
- connection.eventSource = null;
- delete connection.eventSource;
- }
- },
- abort: function (connection, async) {
- transportLogic.ajaxAbort(connection, async);
+ send: function (connection, data) {
+ transportLogic.ajaxSend(connection, data);
+ },
+
+ stop: function (connection) {
+ if (connection && connection.eventSource) {
+ connection.log("EventSource calling close()");
+ connection.eventSource.close();
+ connection.eventSource = null;
+ delete connection.eventSource;
}
},
+ abort: function (connection, async) {
+ transportLogic.ajaxAbort(connection, async);
+ }
+ };
- foreverFrame: {
- name: "foreverFrame",
+}(window.jQuery, window));
+/* jquery.signalR.transports.foreverFrame.js */
+/*global window:false */
+/// <reference path="jquery.signalR.transports.common.js" />
- timeOut: 3000,
+(function ($, window) {
+ "use strict";
- start: function (connection, onSuccess, onFailed) {
- var that = this,
- frameId = (transportLogic.foreverFrame.count += 1),
- url,
- connectTimeOut,
- frame = $("<iframe data-signalr-connection-id='" + connection.id + "' style='position:absolute;top:0;left:0;width:0;height:0;visibility:hidden;'></iframe>");
+ var signalR = $.signalR,
+ events = $.signalR.events,
+ changeState = $.signalR.changeState,
+ transportLogic = signalR.transports._logic;
- if (window.EventSource) {
- // If the browser supports SSE, don't use Forever Frame
- if (onFailed) {
- connection.log("This brower supports SSE, skipping Forever Frame.");
- onFailed();
- }
- return;
- }
+ signalR.transports.foreverFrame = {
+ name: "foreverFrame",
- $(connection).trigger(events.onSending);
+ timeOut: 3000,
- // Build the url
- url = transportLogic.getUrl(connection, this.name);
- url += "&frameId=" + frameId;
+ start: function (connection, onSuccess, onFailed) {
+ var that = this,
+ frameId = (transportLogic.foreverFrame.count += 1),
+ url,
+ connectTimeOut,
+ frame = $("<iframe data-signalr-connection-id='" + connection.id + "' style='position:absolute;top:0;left:0;width:0;height:0;visibility:hidden;'></iframe>");
+
+ if (window.EventSource) {
+ // If the browser supports SSE, don't use Forever Frame
+ if (onFailed) {
+ connection.log("This brower supports SSE, skipping Forever Frame.");
+ onFailed();
+ }
+ return;
+ }
- frame.prop("src", url);
- transportLogic.foreverFrame.connections[frameId] = connection;
+ $(connection).trigger(events.onSending);
- connection.log("Binding to iframe's readystatechange event.");
- frame.bind("readystatechange", function () {
- if ($.inArray(this.readyState, ["loaded", "complete"]) >= 0) {
- connection.log("Forever frame iframe readyState changed to " + this.readyState + ", reconnecting");
+ // Build the url
+ url = transportLogic.getUrl(connection, this.name);
+ url += "&frameId=" + frameId;
- that.reconnect(connection);
- }
- });
+ frame.prop("src", url);
+ transportLogic.foreverFrame.connections[frameId] = connection;
- connection.frame = frame[0];
- connection.frameId = frameId;
+ connection.log("Binding to iframe's readystatechange event.");
+ frame.bind("readystatechange", function () {
+ if ($.inArray(this.readyState, ["loaded", "complete"]) >= 0) {
+ connection.log("Forever frame iframe readyState changed to " + this.readyState + ", reconnecting");
- if (onSuccess) {
- connection.onSuccess = onSuccess;
+ that.reconnect(connection);
}
+ });
- $("body").append(frame);
+ connection.frame = frame[0];
+ connection.frameId = frameId;
- // After connecting, if after the specified timeout there's no response stop the connection
- // and raise on failed
- // REVIEW: Why is connectTimeOut set here and never used again?
- connectTimeOut = window.setTimeout(function () {
- if (connection.onSuccess) {
- connection.log("Failed to connect using forever frame source, it timed out after " + that.timeOut + "ms.");
- that.stop(connection);
-
- if (onFailed) {
- onFailed();
- }
- }
- }, that.timeOut);
- },
+ if (onSuccess) {
+ connection.onSuccess = onSuccess;
+ }
- reconnect: function (connection) {
- var that = this;
- window.setTimeout(function () {
- if (!connection.frame) {
- return;
- }
+ $("body").append(frame);
- if (connection.state === signalR.connectionState.reconnecting ||
- changeState(connection,
- signalR.connectionState.connected,
- signalR.connectionState.reconnecting) === true) {
+ // After connecting, if after the specified timeout there's no response stop the connection
+ // and raise on failed
+ // REVIEW: Why is connectTimeOut set here and never used again?
+ connectTimeOut = window.setTimeout(function () {
+ if (connection.onSuccess) {
+ connection.log("Failed to connect using forever frame source, it timed out after " + that.timeOut + "ms.");
+ that.stop(connection);
- var frame = connection.frame,
- src = transportLogic.getUrl(connection, that.name, true) + "&frameId=" + connection.frameId;
- connection.log("Upating iframe src to '" + src + "'.");
- frame.src = src;
+ if (onFailed) {
+ onFailed();
}
+ }
+ }, that.timeOut);
+ },
- }, connection.reconnectDelay);
- },
-
- send: function (connection, data) {
- transportLogic.ajaxSend(connection, data);
- },
-
- receive: function (connection, data) {
- var cw;
- transportLogic.processMessages(connection, data);
- // Delete the script & div elements
- connection.frameMessageCount = (connection.frameMessageCount || 0) + 1;
- if (connection.frameMessageCount > 50) {
- connection.frameMessageCount = 0;
- cw = connection.frame.contentWindow || connection.frame.contentDocument;
- if (cw && cw.document) {
- $("body", cw.document).empty();
- }
+ reconnect: function (connection) {
+ var that = this;
+ window.setTimeout(function () {
+ if (!connection.frame) {
+ return;
}
- },
- stop: function (connection) {
- var cw = null;
- if (connection.frame) {
- if (connection.frame.stop) {
- connection.frame.stop();
- } else {
- cw = connection.frame.contentWindow || connection.frame.contentDocument;
- if (cw.document && cw.document.execCommand) {
- cw.document.execCommand("Stop");
- }
- }
- $(connection.frame).remove();
- delete transportLogic.foreverFrame.connections[connection.frameId];
- connection.frame = null;
- connection.frameId = null;
- delete connection.frame;
- delete connection.frameId;
- connection.log("Stopping forever frame");
+ if (connection.state === signalR.connectionState.reconnecting ||
+ changeState(connection,
+ signalR.connectionState.connected,
+ signalR.connectionState.reconnecting) === true) {
+
+ var frame = connection.frame,
+ src = transportLogic.getUrl(connection, that.name, true) + "&frameId=" + connection.frameId;
+ connection.log("Upating iframe src to '" + src + "'.");
+ frame.src = src;
}
- },
- abort: function (connection, async) {
- transportLogic.ajaxAbort(connection, async);
- },
+ }, connection.reconnectDelay);
+ },
- getConnection: function (id) {
- return transportLogic.foreverFrame.connections[id];
- },
+ send: function (connection, data) {
+ transportLogic.ajaxSend(connection, data);
+ },
- started: function (connection) {
- if (connection.onSuccess) {
- connection.onSuccess();
- connection.onSuccess = null;
- delete connection.onSuccess;
+ receive: function (connection, data) {
+ var cw;
+ transportLogic.processMessages(connection, data);
+ // Delete the script & div elements
+ connection.frameMessageCount = (connection.frameMessageCount || 0) + 1;
+ if (connection.frameMessageCount > 50) {
+ connection.frameMessageCount = 0;
+ cw = connection.frame.contentWindow || connection.frame.contentDocument;
+ if (cw && cw.document) {
+ $("body", cw.document).empty();
}
- else {
- if (changeState(connection,
- signalR.connectionState.reconnecting,
- signalR.connectionState.connected) === true) {
- // If there's no onSuccess handler we assume this is a reconnect
- $(connection).trigger(events.onReconnect);
+ }
+ },
+
+ stop: function (connection) {
+ var cw = null;
+ if (connection.frame) {
+ if (connection.frame.stop) {
+ connection.frame.stop();
+ } else {
+ cw = connection.frame.contentWindow || connection.frame.contentDocument;
+ if (cw.document && cw.document.execCommand) {
+ cw.document.execCommand("Stop");
}
}
+ $(connection.frame).remove();
+ delete transportLogic.foreverFrame.connections[connection.frameId];
+ connection.frame = null;
+ connection.frameId = null;
+ delete connection.frame;
+ delete connection.frameId;
+ connection.log("Stopping forever frame");
}
},
- longPolling: {
- name: "longPolling",
-
- reconnectDelay: 3000,
+ abort: function (connection, async) {
+ transportLogic.ajaxAbort(connection, async);
+ },
- start: function (connection, onSuccess, onFailed) {
- /// <summary>Starts the long polling connection</summary>
- /// <param name="connection" type="signalR">The SignalR connection to start</param>
- var that = this,
- initialConnectFired = false;
+ getConnection: function (id) {
+ return transportLogic.foreverFrame.connections[id];
+ },
- if (connection.pollXhr) {
- connection.log("Polling xhr requests already exists, aborting.");
- connection.stop();
+ started: function (connection) {
+ if (connection.onSuccess) {
+ connection.onSuccess();
+ connection.onSuccess = null;
+ delete connection.onSuccess;
+ }
+ else {
+ if (changeState(connection,
+ signalR.connectionState.reconnecting,
+ signalR.connectionState.connected) === true) {
+ // If there's no onSuccess handler we assume this is a reconnect
+ $(connection).trigger(events.onReconnect);
}
+ }
+ }
+ };
- connection.messageId = null;
+}(window.jQuery, window));
+/* jquery.signalR.transports.longPolling.js */
+/*global window:false */
+/// <reference path="jquery.signalR.transports.common.js" />
- window.setTimeout(function () {
- (function poll(instance, raiseReconnect) {
- $(instance).trigger(events.onSending);
-
- var messageId = instance.messageId,
- connect = (messageId === null),
- reconnecting = !connect,
- url = transportLogic.getUrl(instance, that.name, reconnecting, raiseReconnect),
- reconnectTimeOut = null,
- reconnectFired = false;
-
- if (reconnecting === true && raiseReconnect === true) {
- if (connection.state !== signalR.connectionState.reconnecting &&
- changeState(connection,
- signalR.connectionState.connected,
- signalR.connectionState.reconnecting) === false) {
- return;
- }
+(function ($, window) {
+ "use strict";
+
+ var signalR = $.signalR,
+ events = $.signalR.events,
+ changeState = $.signalR.changeState,
+ isDisconnecting = $.signalR.isDisconnecting,
+ transportLogic = signalR.transports._logic;
+
+ signalR.transports.longPolling = {
+ name: "longPolling",
+
+ reconnectDelay: 3000,
+
+ start: function (connection, onSuccess, onFailed) {
+ /// <summary>Starts the long polling connection</summary>
+ /// <param name="connection" type="signalR">The SignalR connection to start</param>
+ var that = this,
+ initialConnectFired = false;
+
+ if (connection.pollXhr) {
+ connection.log("Polling xhr requests already exists, aborting.");
+ connection.stop();
+ }
+
+ connection.messageId = null;
+
+ window.setTimeout(function () {
+ (function poll(instance, raiseReconnect) {
+ $(instance).trigger(events.onSending);
+
+ var messageId = instance.messageId,
+ connect = (messageId === null),
+ reconnecting = !connect,
+ url = transportLogic.getUrl(instance, that.name, reconnecting, raiseReconnect),
+ reconnectTimeOut = null,
+ reconnectFired = false;
+
+ if (reconnecting === true && raiseReconnect === true) {
+ if (connection.state !== signalR.connectionState.reconnecting &&
+ changeState(connection,
+ signalR.connectionState.connected,
+ signalR.connectionState.reconnecting) === false) {
+ return;
}
+ }
- connection.log("Attempting to connect to '" + url + "' using longPolling.");
- instance.pollXhr = $.ajax({
- url: url,
- global: false,
- cache: false,
- type: "GET",
- dataType: connection.ajaxDataType,
- success: function (data) {
- var delay = 0,
- timedOutReceived = false;
-
- if (initialConnectFired == false) {
- onSuccess();
- initialConnectFired = true;
- }
+ connection.log("Attempting to connect to '" + url + "' using longPolling.");
+ instance.pollXhr = $.ajax({
+ url: url,
+ global: false,
+ cache: false,
+ type: "GET",
+ dataType: connection.ajaxDataType,
+ success: function (data) {
+ var delay = 0,
+ timedOutReceived = false;
+
+ if (initialConnectFired === false) {
+ onSuccess();
+ initialConnectFired = true;
+ }
- if (raiseReconnect === true) {
- // Fire the reconnect event if it hasn't been fired as yet
- if (reconnectFired === false) {
- connection.log("Raising the reconnect event");
+ if (raiseReconnect === true) {
+ // Fire the reconnect event if it hasn't been fired as yet
+ if (reconnectFired === false) {
+ connection.log("Raising the reconnect event");
- if (changeState(connection,
- signalR.connectionState.reconnecting,
- signalR.connectionState.connected) === true) {
+ if (changeState(connection,
+ signalR.connectionState.reconnecting,
+ signalR.connectionState.connected) === true) {
- $(instance).trigger(events.onReconnect);
- reconnectFired = true;
- }
+ $(instance).trigger(events.onReconnect);
+ reconnectFired = true;
}
}
+ }
- transportLogic.processMessages(instance, data);
- if (data &&
- data.TransportData &&
- $.type(data.TransportData.LongPollDelay) === "number") {
- delay = data.TransportData.LongPollDelay;
- }
+ transportLogic.processMessages(instance, data);
+ if (data &&
+ data.TransportData &&
+ $.type(data.TransportData.LongPollDelay) === "number") {
+ delay = data.TransportData.LongPollDelay;
+ }
- if (data && data.TimedOut) {
- timedOutReceived = data.TimedOut;
- }
+ if (data && data.TimedOut) {
+ timedOutReceived = data.TimedOut;
+ }
- if (data && data.Disconnect) {
- return;
- }
+ if (data && data.Disconnect) {
+ return;
+ }
- if (isDisconnecting(instance) === true) {
- return;
- }
+ if (isDisconnecting(instance) === true) {
+ return;
+ }
- if (delay > 0) {
- window.setTimeout(function () {
- poll(instance, timedOutReceived);
- }, delay);
- } else {
+ if (delay > 0) {
+ window.setTimeout(function () {
poll(instance, timedOutReceived);
- }
- },
-
- error: function (data, textStatus) {
- if (textStatus === "abort") {
- connection.log("Aborted xhr requst.");
- return;
- }
-
- connection.log("An error occurred using longPolling. Status = " + textStatus + ". " + data.responseText);
+ }, delay);
+ } else {
+ poll(instance, timedOutReceived);
+ }
+ },
- if (reconnectTimeOut) {
- // If the request failed then we clear the timeout so that the
- // reconnect event doesn't get fired
- clearTimeout(reconnectTimeOut);
- }
+ error: function (data, textStatus) {
+ if (textStatus === "abort") {
+ connection.log("Aborted xhr requst.");
+ return;
+ }
- $(instance).trigger(events.onError, [data.responseText]);
+ connection.log("An error occurred using longPolling. Status = " + textStatus + ". " + data.responseText);
- window.setTimeout(function () {
- if (isDisconnecting(instance) === false) {
- poll(instance, true);
- }
- }, connection.reconnectDelay);
+ if (reconnectTimeOut) {
+ // If the request failed then we clear the timeout so that the
+ // reconnect event doesn't get fired
+ window.clearTimeout(reconnectTimeOut);
}
- });
- if (raiseReconnect === true) {
- reconnectTimeOut = window.setTimeout(function () {
- if (reconnectFired === false) {
- if (changeState(connection,
- signalR.connectionState.reconnecting,
- signalR.connectionState.connected) === true) {
+ $(instance).trigger(events.onError, [data.responseText]);
- $(instance).trigger(events.onReconnect);
- reconnectFired = true;
- }
+ window.setTimeout(function () {
+ if (isDisconnecting(instance) === false) {
+ poll(instance, true);
}
- },
- that.reconnectDelay);
+ }, connection.reconnectDelay);
}
+ });
- } (connection));
+ if (raiseReconnect === true) {
+ reconnectTimeOut = window.setTimeout(function () {
+ if (reconnectFired === false) {
+ if (changeState(connection,
+ signalR.connectionState.reconnecting,
+ signalR.connectionState.connected) === true) {
- // Now connected
- // There's no good way know when the long poll has actually started so
- // we assume it only takes around 150ms (max) to start the connection
- window.setTimeout(function () {
- if (initialConnectFired === false) {
- onSuccess();
- initialConnectFired = true;
- }
- }, 150);
+ $(instance).trigger(events.onReconnect);
+ reconnectFired = true;
+ }
+ }
+ },
+ that.reconnectDelay);
+ }
- }, 250); // Have to delay initial poll so Chrome doesn't show loader spinner in tab
- },
+ }(connection));
- send: function (connection, data) {
- transportLogic.ajaxSend(connection, data);
- },
+ // Now connected
+ // There's no good way know when the long poll has actually started so
+ // we assume it only takes around 150ms (max) to start the connection
+ window.setTimeout(function () {
+ if (initialConnectFired === false) {
+ onSuccess();
+ initialConnectFired = true;
+ }
+ }, 150);
- stop: function (connection) {
- /// <summary>Stops the long polling connection</summary>
- /// <param name="connection" type="signalR">The SignalR connection to stop</param>
- if (connection.pollXhr) {
- connection.pollXhr.abort();
- connection.pollXhr = null;
- delete connection.pollXhr;
- }
- },
+ }, 250); // Have to delay initial poll so Chrome doesn't show loader spinner in tab
+ },
- abort: function (connection, async) {
- transportLogic.ajaxAbort(connection, async);
+ send: function (connection, data) {
+ transportLogic.ajaxSend(connection, data);
+ },
+
+ stop: function (connection) {
+ /// <summary>Stops the long polling connection</summary>
+ /// <param name="connection" type="signalR">The SignalR connection to stop</param>
+ if (connection.pollXhr) {
+ connection.pollXhr.abort();
+ connection.pollXhr = null;
+ delete connection.pollXhr;
}
+ },
+
+ abort: function (connection, async) {
+ transportLogic.ajaxAbort(connection, async);
}
};
- signalR.noConflict = function () {
- /// <summary>Reinstates the original value of $.connection and returns the signalR object for manual assignment</summary>
- /// <returns type="signalR" />
- if ($.connection === signalR) {
- $.connection = _connection;
+}(window.jQuery, window));
+/* jquery.signalR.hubs.js */
+/*global window:false */
+/// <reference path="jquery.signalR.core.js" />
+
+(function ($, window) {
+ "use strict";
+
+ // we use a global id for tracking callbacks so the server doesn't have to send extra info like hub name
+ var callbackId = 0,
+ callbacks = {};
+
+ // Array.prototype.map
+ if (!Array.prototype.hasOwnProperty("map")) {
+ Array.prototype.map = function (fun, thisp) {
+ var arr = this,
+ i,
+ length = arr.length,
+ result = [];
+ for (i = 0; i < length; i += 1) {
+ if (arr.hasOwnProperty(i)) {
+ result[i] = fun.call(thisp, arr[i], i, arr);
+ }
+ }
+ return result;
+ };
+ }
+
+ function getArgValue(a) {
+ return $.isFunction(a) ? null : ($.type(a) === "undefined" ? null : a);
+ }
+
+ // hubProxy
+ function hubProxy(hubConnection, hubName) {
+ /// <summary>
+ /// Creates a new proxy object for the given hub connection that can be used to invoke
+ /// methods on server hubs and handle client method invocation requests from the server.
+ /// </summary>
+ return new hubProxy.fn.init(hubConnection, hubName);
+ }
+
+ hubProxy.fn = hubProxy.prototype = {
+ init: function (connection, hubName) {
+ this.state = {};
+ this.connection = connection;
+ this.hubName = hubName;
+ },
+
+ on: function (eventName, callback) {
+ /// <summary>Wires up a callback to be invoked when a invocation request is received from the server hub.</summary>
+ /// <param name="eventName" type="String">The name of the hub event to register the callback for.</param>
+ /// <param name="callback" type="Function">The callback to be invoked.</param>
+ var self = this;
+ $(self).bind(eventName, function (e, data) {
+ callback.apply(self, data);
+ });
+ return self;
+ },
+
+ invoke: function (methodName) {
+ /// <summary>Invokes a server hub method with the given arguments.</summary>
+ /// <param name="methodName" type="String">The name of the server hub method.</param>
+
+ var self = this,
+ args = $.makeArray(arguments).slice(1),
+ userCallback = args[args.length - 1], // last argument
+ methodArgs = $.type(userCallback) === "function" ? args.slice(0, -1) /* all but last */ : args,
+ argValues = methodArgs.map(getArgValue),
+ data = { hub: self.hubName, method: methodName, args: argValues, state: self.state, id: callbackId },
+ d = $.Deferred(),
+ callback = function (result) {
+ $.extend(this.state, result.State);
+
+ if (result.Error) {
+ // Server hub method threw an exception, log it & reject the deferred
+ if (result.StackTrace) {
+ self.connection.log(result.Error + "\n" + result.StackTrace);
+ }
+ d.rejectWith(self, [result.Error]);
+ } else {
+ // Server invocation succeeded, invoke any user callback & resolve the deferred
+ if ($.type(userCallback) === "function") {
+ userCallback.call(self, result.Result);
+ }
+ d.resolveWith(self, [result.Result]);
+ }
+ };
+
+ callbacks[callbackId.toString()] = { scope: self, method: callback };
+ callbackId += 1;
+ self.connection.send(window.JSON.stringify(data));
+
+ return d.promise();
}
- return signalR;
};
- if ($.connection) {
- _connection = $.connection;
+ hubProxy.fn.init.prototype = hubProxy.fn;
+
+
+ // hubConnection
+ function hubConnection(url) {
+ /// <summary>Creates a new hub connection.</summary>
+ /// <param name="url" type="String">[Optional] The hub route url, defaults to "/signalr"</param>
+ if (!url) {
+ url = "/signalr";
+ }
+ return new hubConnection.fn.init(url);
}
- $.connection = $.signalR = signalR;
+ hubConnection.fn = hubConnection.prototype = $.connection();
+
+ hubConnection.fn.init = function (url, qs, logging) {
+ var connection = this;
+
+ $.signalR.fn.init.call(connection, url, qs, logging);
+
+ // Object to store hub proxies for this connection
+ connection.proxies = {};
+
+ // Wire up the sending handler
+ connection.sending(function () {
+ var clientHubs = [];
+
+ $.each(this.proxies, function (key) {
+ clientHubs.push({ name: key });
+ });
+
+ this.data = window.JSON.stringify(clientHubs);
+ });
+
+ // Wire up the received handler
+ connection.received(function (data) {
+ var proxy, dataCallbackId, callback;
+ if (!data) {
+ return;
+ }
+
+ if (typeof(data.Id) !== "undefined") {
+ // We received the return value from a server method invocation, look up callback by id and call it
+ dataCallbackId = data.Id.toString();
+ callback = callbacks[dataCallbackId];
+ if (callback) {
+ // Delete the callback from the proxy
+ callbacks[dataCallbackId] = null;
+ delete callbacks[dataCallbackId];
+
+ // Invoke the callback
+ callback.method.call(callback.scope, data);
+ }
+ } else {
+ // We received a client invocation request, i.e. broadcast from server hub
+ // Trigger the local invocation event
+ proxy = this.proxies[data.Hub];
+ $.extend(proxy.state, data.State);
+ $(proxy).trigger(data.Method, [data.Args]);
+ }
+ });
+ };
+
+ hubConnection.fn.createProxy = function (hubName) {
+ /// <summary>
+ /// Creates a new proxy object for the given hub connection that can be used to invoke
+ /// methods on server hubs and handle client method invocation requests from the server.
+ /// </summary>
+ /// <paramater name="hubName" type="String">
+ /// The name of the hub on the server to create the proxy for.
+ /// </parameter>
+ var proxy = this.proxies[hubName];
+ if (!proxy) {
+ proxy = hubProxy(this, hubName);
+ this.proxies[hubName] = proxy;
+ }
+ return proxy;
+ };
+
+ hubConnection.fn.init.prototype = hubConnection.fn;
+
+ $.hubConnection = hubConnection;
-} (window.jQuery, window));
+}(window.jQuery, window));
View
16 samples/SignalR.Hosting.Owin.Samples/Content/Scripts/jquery.signalR.min.js
@@ -1,9 +1,9 @@
/*!
-* SignalR JavaScript Library v0.5.2
-* http://signalr.net/
-*
-* Copyright David Fowler and Damian Edwards 2012
-* Licensed under the MIT.
-* https://github.com/SignalR/SignalR/blob/master/LICENSE.md
-*/
-(function(n,t){"use strict";var u;if(typeof n!="function")throw"SignalR: jQuery not found. Please ensure jQuery is referenced before the SignalR.js file.";if(!t.JSON)throw"SignalR: No JSON parser found. Please ensure json2.js is referenced before the SignalR.js file if you need to support clients without native JSON parsing support, e.g. IE<8.";var i,o,r={onStart:"onStart",onStarting:"onStarting",onSending:"onSending",onReceived:"onReceived",onError:"onError",onReconnect:"onReconnect",onStateChanged:"onStateChanged",onDisconnect:"onDisconnect"},h=function(n,i){if(i!==!1){var r;typeof t.console!="undefined"&&(r="["+(new Date).toTimeString()+"] SignalR: "+n,t.console.debug?t.console.debug(r):t.console.log&&t.console.log(r))}},s=function(i){var r;return(i=n.trim(i),i.indexOf("http")!==0)?!1:(r=t.document.createElement("a"),r.href=i,r.protocol+r.host!==t.location.protocol+t.location.host)},f=function(t,i,u){return i===t.state?(n(t).trigger(r.onStateChanged,[{oldState:t.state,newState:u}]),t.state=u,!0):!1},e=function(n){return n.state===i.connectionState.disconnected};i=function(n,t,r){return new i.fn.init(n,t,r)},i.connectionState={connecting:0,connected:1,reconnecting:2,disconnected:4},i.fn=i.prototype={init:function(n,t,i){this.url=n,this.qs=t,typeof i=="boolean"&&(this.logging=i)},ajaxDataType:"json",logging:!1,state:i.connectionState.disconnected,reconnectDelay:2e3,start:function(u,e){var o=this,h={transport:"auto",jsonp:!1},a,l=n.Deferred(),c=t.document.createElement("a");return f(o,i.connectionState.disconnected,i.connectionState.connecting)===!1?(l.resolve(o),l.promise()):(n.type(u)==="function"?e=u:n.type(u)==="object"&&(n.extend(h,u),n.type(h.callback)==="function"&&(e=h.callback)),c.href=o.url,c.protocol&&c.protocol!==":"?(o.protocol=c.protocol,o.host=c.host,o.baseUrl=c.protocol+"//"+c.host):(o.protocol=t.document.location.protocol,o.host=t.document.location.host,o.baseUrl=o.protocol+"//"+o.host),o.wsProtocol=o.protocol==="https:"?"wss://":"ws://",s(o.url)&&(o.log("Auto detected cross domain url."),h.transport==="auto"&&(h.jsonp||(h.jsonp=!n.support.cors,h.jsonp&&o.log("Using jsonp because this browser doesn't support CORS")),h.transport=h.jsonp===!0?"longPolling":["webSockets","longPolling"])),o.ajaxDataType=h.jsonp?"jsonp":"json",n(o).bind(r.onStart,function(){n.type(e)==="function"&&e.call(o),l.resolve(o)}),a=function(u,e){if(e=e||0,e>=u.length){o.transport||l.reject("SignalR: No transport could be initialized successfully. Try specifying a different transport or none at all for auto initialization.");return}var s=u[e],h=n.type(s)==="object"?s:i.transports[s];h.start(o,function(){o.transport=h,f(o,i.connectionState.connecting,i.connectionState.connected),n(o).trigger(r.onStart),n(t).unload(function(){o.stop(!1)})},function(){a(u,e+1)})},t.setTimeout(function(){var t=o.url+"/negotiate";o.log("Negotiating with '"+t+"'."),n.ajax({url:t,global:!1,cache:!1,type:"GET",data:{},dataType:o.ajaxDataType,error:function(t){n(o).trigger(r.onError,[t.responseText]),l.reject("SignalR: Error during negotiation request: "+t.responseText),o.stop()},success:function(t){if(o.appRelativeUrl=t.Url,o.id=t.ConnectionId,o.webSocketServerUrl=t.WebSocketServerUrl,!t.ProtocolVersion||t.ProtocolVersion!=="1.0"){n(o).trigger(r.onError,"SignalR: Incompatible protocol version."),l.reject("SignalR: Incompatible protocol version.");return}n(o).trigger(r.onStarting);var f=[],u=[];n.each(i.transports,function(n){if(n==="webSockets"&&!t.TryWebSockets)return!0;u.push(n)}),n.isArray(h.transport)?n.each(h.transport,function(){var t=this;(n.type(t)==="object"||n.type(t)==="string"&&n.inArray(""+t,u)>=0)&&f.push(n.type(t)==="string"?""+t:t)}):n.type(h.transport)==="object"||n.inArray(h.transport,u)>=0?f.push(h.transport):f=u,a(f)}})},0),l.promise())},starting:function(t){var i=this,u=n(i);return u.bind(r.onStarting,function(){t.call(i),u.unbind(r.onStarting)}),i},send:function(n){var t=this;if(t.state===i.connectionState.disconnected)throw"SignalR: Connection must be started before data can be sent. Call .start() before .send()";if(t.state===i.connectionState.connecting)throw"SignalR: Connection has not been fully initialized. Use .start().done() or .start().fail() to run logic after the connection has started.";return t.transport.send(t,n),t},sending:function(t){var i=this;return n(i).bind(r.onSending,function(){t.call(i)}),i},received:function(t){var i=this;return n(i).bind(r.onReceived,function(n,r){t.call(i,r)}),i},stateChanged:function(t){var i=this;return n(i).bind(r.onStateChanged,function(n,r){t.call(i,r)}),i},error:function(t){var i=this;return n(i).bind(r.onError,function(n,r){t.call(i,r)}),i},disconnected:function(t){var i=this;return n(i).bind(r.onDisconnect,function(){t.call(i)}),i},reconnected:function(t){var i=this;return n(i).bind(r.onReconnect,function(){t.call(i)}),i},stop:function(t){var u=this;if(u.state!==i.connectionState.disconnected){try{u.transport&&(u.transport.abort(u,t),u.transport.stop(u),u.transport=null),n(u).trigger(r.onDisconnect),delete u.messageId,delete u.groups}finally{f(u,u.state,i.connectionState.disconnected)}return u}},log:function(n){h(n,this.logging)}},i.fn.init.prototype=i.fn,u={addQs:function(i,r){return r.qs?typeof r.qs=="object"?i+"&"+n.param(r.qs):typeof r.qs=="string"?i+"&"+r.qs:i+"&"+t.escape(r.qs.toString()):i},getUrl:function(n,i,r,u){var o=i==="webSockets"?"":n.baseUrl,f=o+n.appRelativeUrl,e="transport="+i+"&connectionId="+t.escape(n.id);return n.data&&(e+="&connectionData="+t.escape(n.data)),r?(u&&(f=f+"/reconnect"),n.messageId&&(e+="&messageId="+n.messageId),n.groups&&(e+="&groups="+t.escape(JSON.stringify(n.groups)))):f=f+"/connect",f+="?"+e,f=this.addQs(f,n),f+="&tid="+Math.floor(Math.random()*11)},ajaxSend:function(i,u){var f=i.url+"/send?transport="+i.transport.name+"&connectionId="+t.escape(i.id);f=this.addQs(f,i),n.ajax({url:f,global:!1,type:"POST",dataType:i.ajaxDataType,data:{data:u},success:function(t){t&&n(i).trigger(r.onReceived,[t])},error:function(t,u){u!=="abort"&&(u!=="parsererror"||i.ajaxDataType!=="jsonp")&&n(i).trigger(r.onError,[t])}})},ajaxAbort:function(i,r){if(typeof i.transport!="undefined"){r=typeof r=="undefined"?!0:r;var u=i.url+"/abort?transport="+i.transport.name+"&connectionId="+t.escape(i.id);u=this.addQs(u,i),n.ajax({url:u,async:r,timeout:1e3,global:!1,type:"POST",dataType:i.ajaxDataType,data:{}}),i.log("Fired ajax abort async = "+r)}},processMessages:function(t,i){var u=n(t);if(i){if(i.Disconnect){t.log("Disconnect command received from server"),t.stop();return}i.Messages&&n.each(i.Messages,function(){try{u.trigger(r.onReceived,[this])}catch(i){t.log("Error raising received "+i),n(t).trigger(r.onError,[i])}}),i.MessageId&&(t.messageId=i.MessageId),i.TransportData&&(t.groups=i.TransportData.Groups)}},foreverFrame:{count:0,connections:{}}},i.transports={webSockets:{name:"webSockets",send:function(n,t){n.socket.send(t)},start:function(e,o,s){var h,a=!1,l=this,c=!o,y,v=n(e);if(t.MozWebSocket&&(t.WebSocket=t.MozWebSocket),!t.WebSocket){s();return}e.socket||(h=e.webSocketServerUrl?e.webSocketServerUrl:e.wsProtocol+e.host,n(e).trigger(r.onSending),h+=u.getUrl(e,this.name,c),e.log("Connecting to websocket endpoint '"+h+"'"),e.socket=new t.WebSocket(h),e.socket.onopen=function(){a=!0,e.log("Websocket opened"),o?o():f(e,i.connectionState.reconnecting,i.connectionState.connected)===!0&&v.trigger(r.onReconnect)},e.socket.onclose=function(t){if(a)typeof t.wasClean!="undefined"&&t.wasClean===!1?(n(e).trigger(r.onError,[t.reason]),e.log("Unclean disconnect from websocket."+t.reason)):e.log("Websocket closed");else{s?s():c&&l.reconnect(e);return}l.reconnect(e)},e.socket.onmessage=function(i){var f=t.JSON.parse(i.data),o;f&&(o=n(e),f.Messages?u.processMessages(e,f):o.trigger(r.onReceived,[f]))})},reconnect:function(n){var r=this;t.setTimeout(function(){r.stop(n),(n.state===i.connectionState.reconnecting||f(n,i.connectionState.connected,i.connectionState.reconnecting)===!0)&&(n.log("Websocket reconnecting"),r.start(n))},n.reconnectDelay)},stop:function(n){n.socket!==null&&(n.log("Closing the Websocket"),n.socket.close(),n.socket=null)},abort:function(){}},serverSentEvents:{name:"serverSentEvents",timeOut:3e3,start:function(e,o,s){var c=this,a=!1,l=n(e),h=!o,y,v;if(e.eventSource&&(e.log("The connection already has an event source. Stopping it."),e.stop()),!t.EventSource){s&&(e.log("This browser doesn't support SSE."),s());return}l.trigger(r.onSending),y=u.getUrl(e,this.name,h);try{e.log("Attempting to connect to SSE endpoint '"+y+"'"),e.eventSource=new t.EventSource(y)}catch(p){e.log("EventSource failed trying to connect with error "+p.Message),s?s():(l.trigger(r.onError,[p]),h&&c.reconnect(e));return}v=t.setTimeout(function(){a===!1&&(e.log("EventSource timed out trying to connect"),e.log("EventSource readyState: "+e.eventSource.readyState),h||c.stop(e),h?e.eventSource.readyState!==t.EventSource.CONNECTING&&e.eventSource.readyState!==t.EventSource.OPEN&&c.reconnect(e):s&&s())},c.timeOut),e.eventSource.addEventListener("open",function(){e.log("EventSource connected"),v&&t.clearTimeout(v),a===!1&&(a=!0,o&&o(),h&&f(e,i.connectionState.reconnecting,i.connectionState.connected)===!0&&l.trigger(r.onReconnect))},!1),e.eventSource.addEventListener("message",function(n){n.data!=="initialized"&&u.processMessages(e,t.JSON.parse(n.data))},!1),e.eventSource.addEventListener("error",function(n){if(!a){s&&s();return}e.log("EventSource readyState: "+e.eventSource.readyState),n.eventPhase===t.EventSource.CLOSED?(e.log("EventSource reconnecting due to the server connection ending"),c.reconnect(e)):(e.log("EventSource error"),l.trigger(r.onError))},!1)},reconnect:function(n){var r=this;t.setTimeout(function(){r.stop(n),(n.state===i.connectionState.reconnecting||f(n,i.connectionState.connected,i.connectionState.reconnecting)===!0)&&(n.log("EventSource reconnecting"),r.start(n))},n.reconnectDelay)},send:function(n,t){u.ajaxSend(n,t)},stop:function(n){n&&n.eventSource&&(n.log("EventSource calling close()"),n.eventSource.close(),n.eventSource=null,delete n.eventSource)},abort:function(n,t){u.ajaxAbort(n,t)}},foreverFrame:{name:"foreverFrame",timeOut:3e3,start:function(i,f,e){var s=this,h=u.foreverFrame.count+=1,c,l,o=n("<iframe data-signalr-connection-id='"+i.id+"' style='position:absolute;top:0;left:0;width:0;height:0;visibility:hidden;'></iframe>");if(t.EventSource){e&&(i.log("This brower supports SSE, skipping Forever Frame."),e());return}n(i).trigger(r.onSending),c=u.getUrl(i,this.name),c+="&frameId="+h,o.prop("src",c),u.foreverFrame.connections[h]=i,i.log("Binding to iframe's readystatechange event."),o.bind("readystatechange",function(){n.inArray(this.readyState,["loaded","complete"])>=0&&(i.log("Forever frame iframe readyState changed to "+this.readyState+", reconnecting"),s.reconnect(i))}),i.frame=o[0],i.frameId=h,f&&(i.onSuccess=f),n("body").append(o),l=t.setTimeout(function(){i.onSuccess&&(i.log("Failed to connect using forever frame source, it timed out after "+s.timeOut+"ms."),s.stop(i),e&&e())},s.timeOut)},reconnect:function(n){var r=this;t.setTimeout(function(){if(n.frame&&(n.state===i.connectionState.reconnecting||f(n,i.connectionState.connected,i.connectionState.reconnecting)===!0)){var e=n.frame,t=u.getUrl(n,r.name,!0)+"&frameId="+n.frameId;n.log("Upating iframe src to '"+t+"'."),e.src=t}},n.reconnectDelay)},send:function(n,t){u.ajaxSend(n,t)},receive:function(t,i){var r;u.processMessages(t,i),t.frameMessageCount=(t.frameMessageCount||0)+1,t.frameMessageCount>50&&(t.frameMessageCount=0,r=t.frame.contentWindow||t.frame.contentDocument,r&&r.document&&n("body",r.document).empty())},stop:function(t){var i=null;t.frame&&(t.frame.stop?t.frame.stop():(i=t.frame.contentWindow||t.frame.contentDocument,i.document&&i.document.execCommand&&i.document.execCommand("Stop")),n(t.frame).remove(),delete u.foreverFrame.connections[t.frameId],t.frame=null,t.frameId=null,delete t.frame,delete t.frameId,t.log("Stopping forever frame"))},abort:function(n,t){u.ajaxAbort(n,t)},getConnection:function(n){return u.foreverFrame.connections[n]},started:function(t){t.onSuccess?(t.onSuccess(),t.onSuccess=null,delete t.onSuccess):f(t,i.connectionState.reconnecting,i.connectionState.connected)===!0&&n(t).trigger(r.onReconnect)}},longPolling:{name:"longPolling",reconnectDelay:3e3,start:function(o,s){var l=this,c=!1;o.pollXhr&&(o.log("Polling xhr requests already exists, aborting."),o.stop()),o.messageId=null,t.setTimeout(function(){(function h(a,v){n(a).trigger(r.onSending);var d=a.messageId,k=d===null,b=!k,w=u.getUrl(a,l.name,b,v),p=null,y=!1;(b!==!0||v!==!0||o.state===i.connectionState.reconnecting||f(o,i.connectionState.connected,i.connectionState.reconnecting)!==!1)&&(o.log("Attempting to connect to '"+w+"' using longPolling."),a.pollXhr=n.ajax({url:w,global:!1,cache:!1,type:"GET",dataType:o.ajaxDataType,success:function(l){var w=0,p=!1;(c==!1&&(s(),c=!0),v===!0&&y===!1&&(o.log("Raising the reconnect event"),f(o,i.connectionState.reconnecting,i.connectionState.connected)===!0&&(n(a).trigger(r.onReconnect),y=!0)),u.processMessages(a,l),l&&l.TransportData&&n.type(l.TransportData.LongPollDelay)==="number"&&(w=l.TransportData.LongPollDelay),l&&l.TimedOut&&(p=l.TimedOut),l&&l.Disconnect)||e(a)!==!0&&(w>0?t.setTimeout(function(){h(a,p)},w):h(a,p))},error:function(i,u){if(u==="abort"){o.log("Aborted xhr requst.");return}o.log("An error occurred using longPolling. Status = "+u+". "+i.responseText),p&&clearTimeout(p),n(a).trigger(r.onError,[i.responseText]),t.setTimeout(function(){e(a)===!1&&h(a,!0)},o.reconnectDelay)}}),v===!0&&(p=t.setTimeout(function(){y===!1&&f(o,i.connectionState.reconnecting,i.connectionState.connected)===!0&&(n(a).trigger(r.onReconnect),y=!0)},l.reconnectDelay)))})(o),t.setTimeout(function(){c===!1&&(s(),c=!0)},150)},250)},send:function(n,t){u.ajaxSend(n,t)},stop:function(n){n.pollXhr&&(n.pollXhr.abort(),n.pollXhr=null,delete n.pollXhr)},abort:function(n,t){u.ajaxAbort(n,t)}}},i.noConflict=function(){return n.connection===i&&(n.connection=o),i},n.connection&&(o=n.connection),n.connection=n.signalR=i})(window.jQuery,window)
+ * SignalR JavaScript Library v0.5.2
+ * http://signalr.net/
+ *
+ * Copyright David Fowler and Damian Edwards 2012
+ * Licensed under the MIT.
+ * https://github.com/SignalR/SignalR/blob/master/LICENSE.md
+ */
+(function(n,t){"use strict";if(typeof n!="function")throw"SignalR: jQuery not found. Please ensure jQuery is referenced before the SignalR.js file.";if(!t.JSON)throw"SignalR: No JSON parser found. Please ensure json2.js is referenced before the SignalR.js file if you need to support clients without native JSON parsing support, e.g. IE<8.";var i,f,r={onStart:"onStart",onStarting:"onStarting",onSending:"onSending",onReceived:"onReceived",onError:"onError",onReconnect:"onReconnect",onStateChanged:"onStateChanged",onDisconnect:"onDisconnect"},o=function(n,i){if(i!==!1){var r;typeof t.console!="undefined"&&(r="["+(new Date).toTimeString()+"] SignalR: "+n,t.console.debug?t.console.debug(r):t.console.log&&t.console.log(r))}},s=function(i){var r;return(i=n.trim(i),i.indexOf("http")!==0)?!1:(r=t.document.createElement("a"),r.href=i,r.protocol+r.host!==t.location.protocol+t.location.host)},u=function(t,i,u){return i===t.state?(n(t).trigger(r.onStateChanged,[{oldState:t.state,newState:u}]),t.state=u,!0):!1},e=function(n){return n.state===i.connectionState.disconnected};i=function(n,t,r){return new i.fn.init(n,t,r)},i.events=r,i.changeState=u,i.isDisconnecting=e,i.connectionState={connecting:0,connected:1,reconnecting:2,disconnected:4},i.hub={start:function(){throw"SignalR: Error loading hubs. Ensure your hubs reference is correct, e.g. <script src='/signalr/hubs'><\/script>.";}},i.fn=i.prototype={init:function(n,t,i){this.url=n,this.qs=t,typeof i=="boolean"&&(this.logging=i)},ajaxDataType:"json",logging:!1,state:i.connectionState.disconnected,reconnectDelay:2e3,start:function(f,e){var o=this,h={transport:"auto",jsonp:!1},a,l=n.Deferred(),c=t.document.createElement("a");return u(o,i.connectionState.disconnected,i.connectionState.connecting)===!1?(l.resolve(o),l.promise()):(n.type(f)==="function"?e=f:n.type(f)==="object"&&(n.extend(h,f),n.type(h.callback)==="function"&&(e=h.callback)),c.href=o.url,c.protocol&&c.protocol!==":"?(o.protocol=c.protocol,o.host=c.host,o.baseUrl=c.protocol+"//"+c.host):(o.protocol=t.document.location.protocol,o.host=t.document.location.host,o.baseUrl=o.protocol+"//"+o.host),o.wsProtocol=o.protocol==="https:"?"wss://":"ws://",s(o.url)&&(o.log("Auto detected cross domain url."),h.transport==="auto"&&(h.jsonp||(h.jsonp=!n.support.cors,h.jsonp&&o.log("Using jsonp because this browser doesn't support CORS")),h.transport=h.jsonp===!0?"longPolling":["webSockets","longPolling"])),o.ajaxDataType=h.jsonp?"jsonp":"json",n(o).bind(r.onStart,function(){n.type(e)==="function"&&e.call(o),l.resolve(o)}),a=function(f,e){if(e=e||0,e>=f.length){o.transport||l.reject("SignalR: No transport could be initialized successfully. Try specifying a different transport or none at all for auto initialization.");return}var s=f[e],h=n.type(s)==="object"?s:i.transports[s];if(s.indexOf("_")===0){a(f,e+1);return}h.start(o,function(){o.transport=h,u(o,i.connectionState.connecting,i.connectionState.connected),n(o).trigger(r.onStart),n(t).unload(function(){o.stop(!1)})},function(){a(f,e+1)})},t.setTimeout(function(){var t=o.url+"/negotiate";o.log("Negotiating with '"+t+"'."),n.ajax({url:t,global:!1,cache:!1,type:"GET",data:{},dataType:o.ajaxDataType,error:function(t){n(o).trigger(r.onError,[t.responseText]),l.reject("SignalR: Error during negotiation request: "+t.responseText),o.stop()},success:function(t){if(o.appRelativeUrl=t.Url,o.id=t.ConnectionId,o.webSocketServerUrl=t.WebSocketServerUrl,!t.ProtocolVersion||t.ProtocolVersion!=="1.0"){n(o).trigger(r.onError,"SignalR: Incompatible protocol version."),l.reject("SignalR: Incompatible protocol version.");return}n(o).trigger(r.onStarting);var f=[],u=[];n.each(i.transports,function(n){if(n==="webSockets"&&!t.TryWebSockets)return!0;u.push(n)}),n.isArray(h.transport)?n.each(h.transport,function(){var t=this;(n.type(t)==="object"||n.type(t)==="string"&&n.inArray(""+t,u)>=0)&&f.push(n.type(t)==="string"?""+t:t)}):n.type(h.transport)==="object"||n.inArray(h.transport,u)>=0?f.push(h.transport):f=u,a(f)}})},0),l.promise())},starting:function(t){var i=this,u=n(i);return u.bind(r.onStarting,function(){t.call(i),u.unbind(r.onStarting)}),i},send:function(n){var t=this;if(t.state===i.connectionState.disconnected)throw"SignalR: Connection must be started before data can be sent. Call .start() before .send()";if(t.state===i.connectionState.connecting)throw"SignalR: Connection has not been fully initialized. Use .start().done() or .start().fail() to run logic after the connection has started.";return t.transport.send(t,n),t},sending:function(t){var i=this;return n(i).bind(r.onSending,function(){t.call(i)}),i},received:function(t){var i=this;return n(i).bind(r.onReceived,function(n,r){t.call(i,r)}),i},stateChanged:function(t){var i=this;return n(i).bind(r.onStateChanged,function(n,r){t.call(i,r)}),i},error:function(t){var i=this;return n(i).bind(r.onError,function(n,r){t.call(i,r)}),i},disconnected:function(t){var i=this;return n(i).bind(r.onDisconnect,function(){t.call(i)}),i},reconnected:function(t){var i=this;return n(i).bind(r.onReconnect,function(){t.call(i)}),i},stop:function(t){var f=this;if(f.state!==i.connectionState.disconnected){try{f.transport&&(f.transport.abort(f,t),f.transport.stop(f),f.transport=null),n(f).trigger(r.onDisconnect),delete f.messageId,delete f.groups}finally{u(f,f.state,i.connectionState.disconnected)}return f}},log:function(n){o(n,this.logging)}},i.fn.init.prototype=i.fn,i.noConflict=function(){return n.connection===i&&(n.connection=f),i},n.connection&&(f=n.connection),n.connection=n.signalR=i})(window.jQuery,window),function(n,t){"use strict";var r=n.signalR,i=n.signalR.events;r.transports={},r.transports._logic={addQs:function(i,r){return r.qs?typeof r.qs=="object"?i+"&"+n.param(r.qs):typeof r.qs=="string"?i+"&"+r.qs:i+"&"+t.escape(r.qs.toString()):i},getUrl:function(n,i,r,u){var o=i==="webSockets"?"":n.baseUrl,f=o+n.appRelativeUrl,e="transport="+i+"&connectionId="+t.escape(n.id);return n.data&&(e+="&connectionData="+t.escape(n.data)),r?(u&&(f=f+"/reconnect"),n.messageId&&(e+="&messageId="+n.messageId),n.groups&&(e+="&groups="+t.escape(JSON.stringify(n.groups)))):f=f+"/connect",f+="?"+e,f=this.addQs(f,n),f+="&tid="+Math.floor(Math.random()*11)},ajaxSend:function(r,u){var f=r.url+"/send?transport="+r.transport.name+"&connectionId="+t.escape(r.id);return f=this.addQs(f,r),n.ajax({url:f,global:!1,type:"POST",dataType:r.ajaxDataType,data:{data:u},success:function(t){t&&n(r).trigger(i.onReceived,[t])},error:function(t,u){u!=="abort"&&(u!=="parsererror"||r.ajaxDataType!=="jsonp")&&n(r).trigger(i.onError,[t])}})},ajaxAbort:function(i,r){if(typeof i.transport!="undefined"){r=typeof r=="undefined"?!0:r;var u=i.url+"/abort?transport="+i.transport.name+"&connectionId="+t.escape(i.id);u=this.addQs(u,i),n.ajax({url:u,async:r,timeout:1e3,global:!1,type:"POST",dataType:i.ajaxDataType,data:{}}),i.log("Fired ajax abort async = "+r)}},processMessages:function(t,r){var u=n(t);if(r){if(r.Disconnect){t.log("Disconnect command received from server"),t.stop();return}r.Messages&&n.each(r.Messages,function(){try{u.trigger(i.onReceived,[this])}catch(r){t.log("Error raising received "+r),n(t).trigger(i.onError,[r])}}),r.MessageId&&(t.messageId=r.MessageId),r.TransportData&&(t.groups=r.TransportData.Groups)}},foreverFrame:{count:0,connections:{}}}}(window.jQuery,window),function(n,t){"use strict";var i=n.signalR,r=n.signalR.events,f=n.signalR.changeState,u=i.transports._logic;i.transports.webSockets={name:"webSockets",send:function(n,t){n.socket.send(t)},start:function(e,o,s){var h,a=!1,l=this,c=!o,v=n(e);if(t.MozWebSocket&&(t.WebSocket=t.MozWebSocket),!t.WebSocket){s();return}e.socket||(h=e.webSocketServerUrl?e.webSocketServerUrl:e.wsProtocol+e.host,n(e).trigger(r.onSending),h+=u.getUrl(e,this.name,c),e.log("Connecting to websocket endpoint '"+h+"'"),e.socket=new t.WebSocket(h),e.socket.onopen=function(){a=!0,e.log("Websocket opened"),o?o():f(e,i.connectionState.reconnecting,i.connectionState.connected)===!0&&v.trigger(r.onReconnect)},e.socket.onclose=function(t){if(a)typeof t.wasClean!="undefined"&&t.wasClean===!1?(n(e).trigger(r.onError,[t.reason]),e.log("Unclean disconnect from websocket."+t.reason)):e.log("Websocket closed");else{s?s():c&&l.reconnect(e);return}l.reconnect(e)},e.socket.onmessage=function(i){var f=t.JSON.parse(i.data),o;f&&(o=n(e),f.Messages?u.processMessages(e,f):o.trigger(r.onReceived,[f]))})},reconnect:function(n){var r=this;t.setTimeout(function(){r.stop(n),(n.state===i.connectionState.reconnecting||f(n,i.connectionState.connected,i.connectionState.reconnecting)===!0)&&(n.log("Websocket reconnecting"),r.start(n))},n.reconnectDelay)},stop:function(n){n.socket!==null&&(n.log("Closing the Websocket"),n.socket.close(),n.socket=null)},abort:function(){}}}(window.jQuery,window),function(n,t){"use strict";var i=n.signalR,u=n.signalR.events,f=n.signalR.changeState,r=i.transports._logic;i.transports.serverSentEvents={name:"serverSentEvents",timeOut:3e3,start:function(e,o,s){var c=this,a=!1,l=n(e),h=!o,y,v;if(e.eventSource&&(e.log("The connection already has an event source. Stopping it."),e.stop()),!t.EventSource){s&&(e.log("This browser doesn't support SSE."),s());return}l.trigger(u.onSending),y=r.getUrl(e,this.name,h);try{e.log("Attempting to connect to SSE endpoint '"+y+"'"),e.eventSource=new t.EventSource(y)}catch(p){e.log("EventSource failed trying to connect with error "+p.Message),s?s():(l.trigger(u.onError,[p]),h&&c.reconnect(e));return}v=t.setTimeout(function(){a===!1&&(e.log("EventSource timed out trying to connect"),e.log("EventSource readyState: "+e.eventSource.readyState),h||c.stop(e),h?e.eventSource.readyState!==t.EventSource.CONNECTING&&e.eventSource.readyState!==t.EventSource.OPEN&&c.reconnect(e):s&&s())},c.timeOut),e.eventSource.addEventListener("open",function(){e.log("EventSource connected"),v&&t.clearTimeout(v),a===!1&&(a=!0,o&&o(),h&&f(e,i.connectionState.reconnecting,i.connectionState.connected)===!0&&l.trigger(u.onReconnect))},!1),e.eventSource.addEventListener("message",function(n){n.data!=="initialized"&&r.processMessages(e,t.JSON.parse(n.data))},!1),e.eventSource.addEventListener("error",function(n){if(!a){s&&s();return}e.log("EventSource readyState: "+e.eventSource.readyState),n.eventPhase===t.EventSource.CLOSED?(e.log("EventSource reconnecting due to the server connection ending"),c.reconnect(e)):(e.log("EventSource error"),l.trigger(u.onError))},!1)},reconnect:function(n){var r=this;t.setTimeout(function(){r.stop(n),(n.state===i.connectionState.reconnecting||f(n,i.connectionState.connected,i.connectionState.reconnecting)===!0)&&(n.log("EventSource reconnecting"),r.start(n))},n.reconnectDelay)},send:function(n,t){r.ajaxSend(n,t)},stop:function(n){n&&n.eventSource&&(n.log("EventSource calling close()"),n.eventSource.close(),n.eventSource=null,delete n.eventSource)},abort:function(n,t){r.ajaxAbort(n,t)}}}(window.jQuery,window),function(n,t){"use strict";var r=n.signalR,u=n.signalR.events,f=n.signalR.changeState,i=r.transports._logic;r.transports.foreverFrame={name:"foreverFrame",timeOut:3e3,start:function(r,f,e){var s=this,h=i.foreverFrame.count+=1,c,l,o=n("<iframe data-signalr-connection-id='"+r.id+"' style='position:absolute;top:0;left:0;width:0;height:0;visibility:hidden;'></iframe>");if(t.EventSource){e&&(r.log("This brower supports SSE, skipping Forever Frame."),e());return}n(r).trigger(u.onSending),c=i.getUrl(r,this.name),c+="&frameId="+h,o.prop("src",c),i.foreverFrame.connections[h]=r,r.log("Binding to iframe's readystatechange event."),o.bind("readystatechange",function(){n.inArray(this.readyState,["loaded","complete"])>=0&&(r.log("Forever frame iframe readyState changed to "+this.readyState+", reconnecting"),s.reconnect(r))}),r.frame=o[0],r.frameId=h,f&&(r.onSuccess=f),n("body").append(o),l=t.setTimeout(function(){r.onSuccess&&(r.log("Failed to connect using forever frame source, it timed out after "+s.timeOut+"ms."),s.stop(r),e&&e())},s.timeOut)},reconnect:function(n){var u=this;t.setTimeout(function(){if(n.frame&&(n.state===r.connectionState.reconnecting||f(n,r.connectionState.connected,r.connectionState.reconnecting)===!0)){var e=n.frame,t=i.getUrl(n,u.name,!0)+"&frameId="+n.frameId;n.log("Upating iframe src to '"+t+"'."),e.src=t}},n.reconnectDelay)},send:function(n,t){i.ajaxSend(n,t)},receive:function(t,r){var u;i.processMessages(t,r),t.frameMessageCount=(t.frameMessageCount||0)+1,t.frameMessageCount>50&&(t.frameMessageCount=0,u=t.frame.contentWindow||t.frame.contentDocument,u&&u.document&&n("body",u.document).empty())},stop:function(t){var r=null;t.frame&&(t.frame.stop?t.frame.stop():(r=t.frame.contentWindow||t.frame.contentDocument,r.document&&r.document.execCommand&&r.document.execCommand("Stop")),n(t.frame).remove(),delete i.foreverFrame.connections[t.frameId],t.frame=null,t.frameId=null,delete t.frame,delete t.frameId,t.log("Stopping forever frame"))},abort:function(n,t){i.ajaxAbort(n,t)},getConnection:function(n){return i.foreverFrame.connections[n]},started:function(t){t.onSuccess?(t.onSuccess(),t.onSuccess=null,delete t.onSuccess):f(t,r.connectionState.reconnecting,r.connectionState.connected)===!0&&n(t).trigger(u.onReconnect)}}}(window.jQuery,window),function(n,t){"use strict";var i=n.signalR,u=n.signalR.events,f=n.signalR.changeState,e=n.signalR.isDisconnecting,r=i.transports._logic;i.transports.longPolling={name:"longPolling",reconnectDelay:3e3,start:function(o,s){var l=this,c=!1;o.pollXhr&&(o.log("Polling xhr requests already exists, aborting."),o.stop()),o.messageId=null,t.setTimeout(function(){(function h(a,v){n(a).trigger(u.onSending);var d=a.messageId,k=d===null,b=!k,w=r.getUrl(a,l.name,b,v),p=null,y=!1;(b!==!0||v!==!0||o.state===i.connectionState.reconnecting||f(o,i.connectionState.connected,i.connectionState.reconnecting)!==!1)&&(o.log("Attempting to connect to '"+w+"' using longPolling."),a.pollXhr=n.ajax({url:w,global:!1,cache:!1,type:"GET",dataType:o.ajaxDataType,success:function(l){var w=0,p=!1;(c===!1&&(s(),c=!0),v===!0&&y===!1&&(o.log("Raising the reconnect event"),f(o,i.connectionState.reconnecting,i.connectionState.connected)===!0&&(n(a).trigger(u.onReconnect),y=!0)),r.processMessages(a,l),l&&l.TransportData&&n.type(l.TransportData.LongPollDelay)==="number"&&(w=l.TransportData.LongPollDelay),l&&l.TimedOut&&(p=l.TimedOut),l&&l.Disconnect)||e(a)!==!0&&(w>0?t.setTimeout(function(){h(a,p)},w):h(a,p))},error:function(i,r){if(r==="abort"){o.log("Aborted xhr requst.");return}o.log("An error occurred using longPolling. Status = "+r+". "+i.responseText),p&&t.clearTimeout(p),n(a).trigger(u.onError,[i.responseText]),t.setTimeout(function(){e(a)===!1&&h(a,!0)},o.reconnectDelay)}}),v===!0&&(p=t.setTimeout(function(){y===!1&&f(o,i.connectionState.reconnecting,i.connectionState.connected)===!0&&(n(a).trigger(u.onReconnect),y=!0)},l.reconnectDelay)))})(o),t.setTimeout(function(){c===!1&&(s(),c=!0)},150)},250)},send:function(n,t){r.ajaxSend(n,t)},stop:function(n){n.pollXhr&&(n.pollXhr.abort(),n.pollXhr=null,delete n.pollXhr)},abort:function(n,t){r.ajaxAbort(n,t)}}}(window.jQuery,window),function(n,t){"use strict";function e(t){return n.isFunction(t)?null:n.type(t)==="undefined"?null:t}function r(n,t){return new r.fn.init(n,t)}function i(n){return n||(n="/signalr"),new i.fn.init(n)}var f=0,u={};Array.prototype.hasOwnProperty("map")||(Array.prototype.map=function(n,t){for(var r=this,f=r.length,u=[],i=0;i<f;i+=1)r.hasOwnProperty(i)&&(u[i]=n.call(t,r[i],i,r));return u}),r.fn=r.prototype={init:function(n,t){this.state={},this.connection=n,this.hubName=t},on:function(t,i){var r=this;return n(r).bind(t,function(n,t){i.apply(r,t)}),r},invoke:function(i){var r=this,o=n.makeArray(arguments).slice(1),h=o[o.length-1],a=n.type(h)==="function"?o.slice(0,-1):o,v=a.map(e),l={hub:r.hubName,method:i,args:v,state:r.state,id:f},s=n.Deferred(),c=function(t){n.extend(this.state,t.State),t.Error?(t.StackTrace&&r.connection.log(t.Error+"\n"+t.StackTrace),s.rejectWith(r,[t.Error])):(n.type(h)==="function"&&h.call(r,t.Result),s.resolveWith(r,[t.Result]))};return u[f.toString()]={scope:r,method:c},f+=1,r.connection.send(t.JSON.stringify(l)),s.promise()}},r.fn.init.prototype=r.fn,i.fn=i.prototype=n.connection(),i.fn.init=function(i,r,f){var e=this;n.signalR.fn.init.call(e,i,r,f),e.proxies={},e.sending(function(){var i=[];n.each(this.proxies,function(n){i.push({name:n})}),this.data=t.JSON.stringify(i)}),e.received(function(t){var f,i,r;t&&(typeof t.Id!="undefined"?(i=t.Id.toString(),r=u[i],r&&(u[i]=null,delete u[i],r.method.call(r.scope,t))):(f=this.proxies[t.Hub],n.extend(f.state,t.State),n(f).trigger(t.Method,[t.Args])))})},i.fn.createProxy=function(n){var t=this.proxies[n];return t||(t=r(this,n),this.proxies[n]=t),t},i.fn.init.prototype=i.fn,n.hubConnection=i}(window.jQuery,window)
Please sign in to comment.
Something went wrong with that request. Please try again.