From ef99a12b7c2c3b7331dd28885fa493a8a371a93c Mon Sep 17 00:00:00 2001 From: Drew Marsh Date: Sun, 12 Feb 2012 14:56:22 -0800 Subject: [PATCH] Fix for bug in signalR::stop - Fixed bug in signalR::stop where there was $connection.triggerEvent call, but there's no $connection variable in scope. Should be $(connection).triggerEvent. - Also added pre-build copying of jquery.signalR[.min] scripts to the Owin samples project. --- .../Scripts/jquery.signalR.js | 2 +- .../Scripts/jquery.signalR.min.js | 2 +- .../Content/Scripts/jquery.signalR.js | 178 ++++++++++++------ .../Content/Scripts/jquery.signalR.min.js | 2 +- .../SignalR.Hosting.Owin.Samples.csproj | 11 +- .../SignalR.Hosting.Owin.csproj | 7 - SignalR/Scripts/jquery.signalR.js | 2 +- SignalR/Scripts/jquery.signalR.min.js | 2 +- 8 files changed, 128 insertions(+), 78 deletions(-) diff --git a/SignalR.Hosting.AspNet.Samples/Scripts/jquery.signalR.js b/SignalR.Hosting.AspNet.Samples/Scripts/jquery.signalR.js index c877e05772..ad467bc213 100644 --- a/SignalR.Hosting.AspNet.Samples/Scripts/jquery.signalR.js +++ b/SignalR.Hosting.AspNet.Samples/Scripts/jquery.signalR.js @@ -282,7 +282,7 @@ delete connection.groups; // Trigger the disconnect event - $connection.trigger(events.onDisconnect); + $(connection).trigger(events.onDisconnect); return connection; }, diff --git a/SignalR.Hosting.AspNet.Samples/Scripts/jquery.signalR.min.js b/SignalR.Hosting.AspNet.Samples/Scripts/jquery.signalR.min.js index 9e99f53a38..aae488b71d 100644 --- a/SignalR.Hosting.AspNet.Samples/Scripts/jquery.signalR.min.js +++ b/SignalR.Hosting.AspNet.Samples/Scripts/jquery.signalR.min.js @@ -1 +1 @@ -(function(n,t){"use strict";var f,e,i,r,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.";i={onStart:"onStart",onStarting:"onStarting",onSending:"onSending",onReceived:"onReceived",onError:"onError",onReconnect:"onReconnect",onDisconnect:"onDisconnect"},r=function(n,i){if(i===!1)return;var r;if(typeof t.console=="undefined")return;r="["+(new Date).toTimeString()+"] SignalR: "+n,t.console.debug?t.console.debug(r):t.console.log&&t.console.log(r)},f=function(n,t,i){return new f.fn.init(n,t,i)},f.fn=f.prototype={init:function(n,t,i){this.url=n,this.qs=t,typeof i=="boolean"&&(this.logging=i)},logging:!1,reconnectDelay:2e3,start:function(r,u){var e=this,o={transport:"auto"},h,s=n.Deferred();return e.transport?(s.resolve(e),s):(n.type(r)==="function"?u=r:n.type(r)==="object"&&(n.extend(o,r),n.type(o.callback)==="function"&&(u=o.callback)),n(e).bind(i.onStart,function(){n.type(u)==="function"&&u.call(e),s.resolve(e)}),h=function(t,r){r=r||0;if(r>=t.length){e.transport||s.reject("SignalR: No transport could be initialized successfully. Try specifying a different transport or none at all for auto initialization.");return}var u=t[r],o=n.type(u)==="object"?u:f.transports[u];o.start(e,function(){e.transport=o,n(e).trigger(i.onStart)},function(){h(t,r+1)})},t.setTimeout(function(){n.ajax(e.url+"/negotiate",{global:!1,type:"POST",data:{},error:function(t){n(e).trigger(i.onError,[t]),s.reject("SignalR: Error during negotiation request: "+t)},success:function(t){e.appRelativeUrl=t.Url,e.id=t.ConnectionId,e.webSocketServerUrl=t.WebSocketServerUrl;if(!t.ProtocolVersion||t.ProtocolVersion!=="1.0"){n(e).trigger(i.onError,"SignalR: Incompatible protocol version."),s.reject("SignalR: Incompatible protocol version.");return}n(e).trigger(i.onStarting);var u=[],r=[];n.each(f.transports,function(n){if(n==="webSockets"&&!t.TryWebSockets)return!0;r.push(n)}),n.isArray(o.transport)?n.each(o.transport,function(){var t=this;n.type(t)!=="object"&&(n.type(t)!=="string"||n.inArray(""+t,r)<0)||u.push(n.type(t)==="string"?""+t:t)}):n.type(o.transport)!=="object"&&n.inArray(o.transport,r)<0?u=r:u.push(o.transport),h(u)}})},0),s)},starting:function(t){var r=this,u=n(r);return u.bind(i.onStarting,function(){t.call(r),u.unbind(i.onStarting)}),r},send:function(n){var t=this;if(!t.transport)throw"SignalR: Connection must be started before data can be sent. Call .start() before .send()";return t.transport.send(t,n),t},sending:function(t){var r=this;return n(r).bind(i.onSending,function(){t.call(r)}),r},received:function(t){var r=this;return n(r).bind(i.onReceived,function(n,i){t.call(r,i)}),r},error:function(t){var r=this;return n(r).bind(i.onError,function(n,i){t.call(r,i)}),r},disconnected:function(t){var r=this;return n(r).bind(i.onDisconnect,function(){t.call(r)}),r},reconnected:function(t){var r=this;return n(r).bind(i.onReconnect,function(){t.call(r)}),r},stop:function(){var n=this;return n.transport&&(n.transport.stop(n),n.transport=null),delete n.messageId,delete n.groups,$connection.trigger(i.onDisconnect),n},log:r},f.fn.init.prototype=f.fn,u={addQs:function(t,i){return i.qs?typeof i.qs=="object"?t+"&"+n.param(i.qs):typeof i.qs=="string"?t+"&"+i.qs:t+"&"+escape(i.qs.toString()):t},getUrl:function(n,i,r){var u=n.url,f="transport="+i+"&connectionId="+t.escape(n.id);return n.data&&(f+="&connectionData="+t.escape(n.data)),r?(n.messageId&&(f+="&messageId="+n.messageId),n.groups&&(f+="&groups="+t.escape(JSON.stringify(n.groups)))):u=u+"/connect",u+="?"+f,u=this.addQs(u,n)},ajaxSend:function(r,u){var f=r.url+"/send?transport="+r.transport.name+"&connectionId="+t.escape(r.id);f=this.addQs(f,r),n.ajax(f,{global:!1,type:"POST",dataType:"json",data:{data:u},success:function(t){t&&n(r).trigger(i.onReceived,[t])},error:function(t,u){if(u==="abort")return;n(r).trigger(i.onError,[t])}})},processMessages:function(t,u){var f=n(t);if(u){if(u.Disconnect){r("Disconnect command received from server",t.logging),t.stop(),f.trigger(i.onDisconnect);return}u.Messages&&n.each(u.Messages,function(){try{f.trigger(i.onReceived,[this])}catch(u){r("Error raising received "+u,t.logging),n(t).trigger(i.onError,[u])}}),t.messageId=u.MessageId,t.groups=u.TransportData.Groups}},foreverFrame:{count:0,connections:{}}},f.transports={webSockets:{name:"webSockets",send:function(n,t){n.socket.send(t)},start:function(u,f,e){var o,h=!1,s;t.MozWebSocket&&(t.WebSocket=t.MozWebSocket);if(!t.WebSocket){e();return}u.socket||(u.webSocketServerUrl?o=u.webSocketServerUrl:(s=document.location.protocol==="https:"?"wss://":"ws://",o=s+document.location.host+u.appRelativeUrl),n(u).trigger(i.onSending),o+=u.data?"?connectionData="+u.data+"&transport=webSockets&connectionId="+u.id:"?transport=webSockets&connectionId="+u.id,u.socket=new t.WebSocket(o),u.socket.onopen=function(){h=!0,f&&f()},u.socket.onclose=function(t){h?typeof t.wasClean!="undefined"&&t.wasClean===!1&&n(u).trigger(i.onError):e&&e(),u.socket=null},u.socket.onmessage=function(f){var e=t.JSON.parse(f.data),o;e&&(o=n(u),e.Messages?n.each(e.Messages,function(){try{o.trigger(i.onReceived,[this])}catch(n){r("Error raising received "+n,u.logging)}}):o.trigger(i.onReceived,[e]))})},stop:function(n){n.socket!==null&&(n.socket.close(),n.socket=null)}},serverSentEvents:{name:"serverSentEvents",timeOut:3e3,start:function(f,e,o){var s=this,l=!1,c=n(f),h=!e,v,a;f.eventSource&&f.stop();if(!t.EventSource){o&&o();return}c.trigger(i.onSending),v=u.getUrl(f,this.name,h);try{f.eventSource=new t.EventSource(v)}catch(y){r("EventSource failed trying to connect with error "+y.Message,f.logging),o?o():(c.trigger(i.onError,[y]),h&&(r("EventSource reconnecting",f.logging),s.reconnect(f)));return}a=t.setTimeout(function(){l===!1&&(r("EventSource timed out trying to connect",f.logging),o&&o(),h?(r("EventSource reconnecting",f.logging),s.reconnect(f)):s.stop(f))},s.timeOut),f.eventSource.addEventListener("open",function(){r("EventSource connected",f.logging),a&&t.clearTimeout(a),l===!1&&(l=!0,e&&e(),h&&c.trigger(i.onReconnect))},!1),f.eventSource.addEventListener("message",function(n){if(n.data==="initialized")return;u.processMessages(f,t.JSON.parse(n.data))},!1),f.eventSource.addEventListener("error",function(n){if(!l){o&&o();return}r("EventSource readyState: "+f.eventSource.readyState,f.logging),n.eventPhase===t.EventSource.CLOSED?f.eventSource.readyState===t.EventSource.CONNECTING?(r("EventSource reconnecting due to the server connection ending",f.logging),s.reconnect(f)):(r("EventSource closed",f.logging),s.stop(f)):(r("EventSource error",f.logging),c.trigger(i.onError))},!1)},reconnect:function(n){var i=this;t.setTimeout(function(){i.stop(n),i.start(n)},n.reconnectDelay)},send:function(n,t){u.ajaxSend(n,t)},stop:function(n){n&&n.eventSource&&(n.eventSource.close(),n.eventSource=null,delete n.eventSource)}},foreverFrame:{name:"foreverFrame",timeOut:3e3,start:function(f,e,o){var h=this,l=u.foreverFrame.count+=1,c,a,s=n("");if(t.EventSource){o&&o();return}n(f).trigger(i.onSending),c=u.getUrl(f,this.name),c+="&frameId="+l,s.prop("src",c),u.foreverFrame.connections[l]=f,s.bind("readystatechange",function(){n.inArray(this.readyState,["loaded","complete"])<0||(r("Forever frame iframe readyState changed to "+this.readyState+", reconnecting",f.logging),h.reconnect(f))}),f.frame=s[0],f.frameId=l,e&&(f.onSuccess=e),n("body").append(s),a=t.setTimeout(function(){f.onSuccess&&(h.stop(f),o&&o())},h.timeOut)},reconnect:function(n){var i=this;t.setTimeout(function(){var r=n.frame,t=u.getUrl(n,i.name,!0)+"&frameId="+n.frameId;r.src=t},n.reconnectDelay)},send:function(n,t){u.ajaxSend(n,t)},receive:u.processMessages,stop:function(t){t.frame&&(t.frame.stop?t.frame.stop():t.frame.document&&t.frame.document.execCommand&&t.frame.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)},getConnection:function(n){return u.foreverFrame.connections[n]},started:function(t){t.onSuccess?(t.onSuccess(),t.onSuccess=null,delete t.onSuccess):n(t).trigger(i.onReconnect)}},longPolling:{name:"longPolling",reconnectDelay:3e3,start:function(r,f){var o=this;r.pollXhr&&r.stop(),r.messageId=null,t.setTimeout(function(){(function e(f,s){n(f).trigger(i.onSending);var a=f.messageId,l=a===null,v=u.getUrl(f,o.name,!l),c=null,h=!1;f.pollXhr=n.ajax(v,{global:!1,type:"GET",dataType:"json",success:function(r){var c=0,o=!1;s===!0&&h===!1&&(n(f).trigger(i.onReconnect),h=!0),u.processMessages(f,r),r&&n.type(r.TransportData.LongPollDelay)==="number"&&(c=r.TransportData.LongPollDelay),r&&r.TimedOut&&(o=r.TimedOut),c>0?t.setTimeout(function(){e(f,o)},c):e(f,o)},error:function(u,o){if(o==="abort")return;c&&clearTimeout(c),n(f).trigger(i.onError,[u]),t.setTimeout(function(){e(f,!0)},r.reconnectDelay)}}),s===!0&&(c=t.setTimeout(function(){h===!1&&(n(f).trigger(i.onReconnect),h=!0)},o.reconnectDelay))})(r),t.setTimeout(f,150)},250)},send:function(n,t){u.ajaxSend(n,t)},stop:function(n){n.pollXhr&&(n.pollXhr.abort(),n.pollXhr=null,delete n.pollXhr)}}},f.noConflict=function(){return n.connection===f&&(n.connection=e),f},n.connection&&(e=n.connection),n.connection=n.signalR=f})(window.jQuery,window) \ No newline at end of file +(function(n,t){"use strict";var f,e,i,r,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.";i={onStart:"onStart",onStarting:"onStarting",onSending:"onSending",onReceived:"onReceived",onError:"onError",onReconnect:"onReconnect",onDisconnect:"onDisconnect"},r=function(n,i){if(i===!1)return;var r;if(typeof t.console=="undefined")return;r="["+(new Date).toTimeString()+"] SignalR: "+n,t.console.debug?t.console.debug(r):t.console.log&&t.console.log(r)},f=function(n,t,i){return new f.fn.init(n,t,i)},f.fn=f.prototype={init:function(n,t,i){this.url=n,this.qs=t,typeof i=="boolean"&&(this.logging=i)},logging:!1,reconnectDelay:2e3,start:function(r,u){var e=this,o={transport:"auto"},h,s=n.Deferred();return e.transport?(s.resolve(e),s):(n.type(r)==="function"?u=r:n.type(r)==="object"&&(n.extend(o,r),n.type(o.callback)==="function"&&(u=o.callback)),n(e).bind(i.onStart,function(){n.type(u)==="function"&&u.call(e),s.resolve(e)}),h=function(t,r){r=r||0;if(r>=t.length){e.transport||s.reject("SignalR: No transport could be initialized successfully. Try specifying a different transport or none at all for auto initialization.");return}var u=t[r],o=n.type(u)==="object"?u:f.transports[u];o.start(e,function(){e.transport=o,n(e).trigger(i.onStart)},function(){h(t,r+1)})},t.setTimeout(function(){n.ajax(e.url+"/negotiate",{global:!1,type:"POST",data:{},error:function(t){n(e).trigger(i.onError,[t]),s.reject("SignalR: Error during negotiation request: "+t)},success:function(t){e.appRelativeUrl=t.Url,e.id=t.ConnectionId,e.webSocketServerUrl=t.WebSocketServerUrl;if(!t.ProtocolVersion||t.ProtocolVersion!=="1.0"){n(e).trigger(i.onError,"SignalR: Incompatible protocol version."),s.reject("SignalR: Incompatible protocol version.");return}n(e).trigger(i.onStarting);var u=[],r=[];n.each(f.transports,function(n){if(n==="webSockets"&&!t.TryWebSockets)return!0;r.push(n)}),n.isArray(o.transport)?n.each(o.transport,function(){var t=this;n.type(t)!=="object"&&(n.type(t)!=="string"||n.inArray(""+t,r)<0)||u.push(n.type(t)==="string"?""+t:t)}):n.type(o.transport)!=="object"&&n.inArray(o.transport,r)<0?u=r:u.push(o.transport),h(u)}})},0),s)},starting:function(t){var r=this,u=n(r);return u.bind(i.onStarting,function(){t.call(r),u.unbind(i.onStarting)}),r},send:function(n){var t=this;if(!t.transport)throw"SignalR: Connection must be started before data can be sent. Call .start() before .send()";return t.transport.send(t,n),t},sending:function(t){var r=this;return n(r).bind(i.onSending,function(){t.call(r)}),r},received:function(t){var r=this;return n(r).bind(i.onReceived,function(n,i){t.call(r,i)}),r},error:function(t){var r=this;return n(r).bind(i.onError,function(n,i){t.call(r,i)}),r},disconnected:function(t){var r=this;return n(r).bind(i.onDisconnect,function(){t.call(r)}),r},reconnected:function(t){var r=this;return n(r).bind(i.onReconnect,function(){t.call(r)}),r},stop:function(){var t=this;return t.transport&&(t.transport.stop(t),t.transport=null),delete t.messageId,delete t.groups,n(t).trigger(i.onDisconnect),t},log:r},f.fn.init.prototype=f.fn,u={addQs:function(t,i){return i.qs?typeof i.qs=="object"?t+"&"+n.param(i.qs):typeof i.qs=="string"?t+"&"+i.qs:t+"&"+escape(i.qs.toString()):t},getUrl:function(n,i,r){var u=n.url,f="transport="+i+"&connectionId="+t.escape(n.id);return n.data&&(f+="&connectionData="+t.escape(n.data)),r?(n.messageId&&(f+="&messageId="+n.messageId),n.groups&&(f+="&groups="+t.escape(JSON.stringify(n.groups)))):u=u+"/connect",u+="?"+f,u=this.addQs(u,n)},ajaxSend:function(r,u){var f=r.url+"/send?transport="+r.transport.name+"&connectionId="+t.escape(r.id);f=this.addQs(f,r),n.ajax(f,{global:!1,type:"POST",dataType:"json",data:{data:u},success:function(t){t&&n(r).trigger(i.onReceived,[t])},error:function(t,u){if(u==="abort")return;n(r).trigger(i.onError,[t])}})},processMessages:function(t,u){var f=n(t);if(u){if(u.Disconnect){r("Disconnect command received from server",t.logging),t.stop(),f.trigger(i.onDisconnect);return}u.Messages&&n.each(u.Messages,function(){try{f.trigger(i.onReceived,[this])}catch(u){r("Error raising received "+u,t.logging),n(t).trigger(i.onError,[u])}}),t.messageId=u.MessageId,t.groups=u.TransportData.Groups}},foreverFrame:{count:0,connections:{}}},f.transports={webSockets:{name:"webSockets",send:function(n,t){n.socket.send(t)},start:function(u,f,e){var o,h=!1,s;t.MozWebSocket&&(t.WebSocket=t.MozWebSocket);if(!t.WebSocket){e();return}u.socket||(u.webSocketServerUrl?o=u.webSocketServerUrl:(s=document.location.protocol==="https:"?"wss://":"ws://",o=s+document.location.host+u.appRelativeUrl),n(u).trigger(i.onSending),o+=u.data?"?connectionData="+u.data+"&transport=webSockets&connectionId="+u.id:"?transport=webSockets&connectionId="+u.id,u.socket=new t.WebSocket(o),u.socket.onopen=function(){h=!0,f&&f()},u.socket.onclose=function(t){h?typeof t.wasClean!="undefined"&&t.wasClean===!1&&n(u).trigger(i.onError):e&&e(),u.socket=null},u.socket.onmessage=function(f){var e=t.JSON.parse(f.data),o;e&&(o=n(u),e.Messages?n.each(e.Messages,function(){try{o.trigger(i.onReceived,[this])}catch(n){r("Error raising received "+n,u.logging)}}):o.trigger(i.onReceived,[e]))})},stop:function(n){n.socket!==null&&(n.socket.close(),n.socket=null)}},serverSentEvents:{name:"serverSentEvents",timeOut:3e3,start:function(f,e,o){var s=this,l=!1,c=n(f),h=!e,v,a;f.eventSource&&f.stop();if(!t.EventSource){o&&o();return}c.trigger(i.onSending),v=u.getUrl(f,this.name,h);try{f.eventSource=new t.EventSource(v)}catch(y){r("EventSource failed trying to connect with error "+y.Message,f.logging),o?o():(c.trigger(i.onError,[y]),h&&(r("EventSource reconnecting",f.logging),s.reconnect(f)));return}a=t.setTimeout(function(){l===!1&&(r("EventSource timed out trying to connect",f.logging),o&&o(),h?(r("EventSource reconnecting",f.logging),s.reconnect(f)):s.stop(f))},s.timeOut),f.eventSource.addEventListener("open",function(){r("EventSource connected",f.logging),a&&t.clearTimeout(a),l===!1&&(l=!0,e&&e(),h&&c.trigger(i.onReconnect))},!1),f.eventSource.addEventListener("message",function(n){if(n.data==="initialized")return;u.processMessages(f,t.JSON.parse(n.data))},!1),f.eventSource.addEventListener("error",function(n){if(!l){o&&o();return}r("EventSource readyState: "+f.eventSource.readyState,f.logging),n.eventPhase===t.EventSource.CLOSED?f.eventSource.readyState===t.EventSource.CONNECTING?(r("EventSource reconnecting due to the server connection ending",f.logging),s.reconnect(f)):(r("EventSource closed",f.logging),s.stop(f)):(r("EventSource error",f.logging),c.trigger(i.onError))},!1)},reconnect:function(n){var i=this;t.setTimeout(function(){i.stop(n),i.start(n)},n.reconnectDelay)},send:function(n,t){u.ajaxSend(n,t)},stop:function(n){n&&n.eventSource&&(n.eventSource.close(),n.eventSource=null,delete n.eventSource)}},foreverFrame:{name:"foreverFrame",timeOut:3e3,start:function(f,e,o){var h=this,l=u.foreverFrame.count+=1,c,a,s=n("");if(t.EventSource){o&&o();return}n(f).trigger(i.onSending),c=u.getUrl(f,this.name),c+="&frameId="+l,s.prop("src",c),u.foreverFrame.connections[l]=f,s.bind("readystatechange",function(){n.inArray(this.readyState,["loaded","complete"])<0||(r("Forever frame iframe readyState changed to "+this.readyState+", reconnecting",f.logging),h.reconnect(f))}),f.frame=s[0],f.frameId=l,e&&(f.onSuccess=e),n("body").append(s),a=t.setTimeout(function(){f.onSuccess&&(h.stop(f),o&&o())},h.timeOut)},reconnect:function(n){var i=this;t.setTimeout(function(){var r=n.frame,t=u.getUrl(n,i.name,!0)+"&frameId="+n.frameId;r.src=t},n.reconnectDelay)},send:function(n,t){u.ajaxSend(n,t)},receive:u.processMessages,stop:function(t){t.frame&&(t.frame.stop?t.frame.stop():t.frame.document&&t.frame.document.execCommand&&t.frame.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)},getConnection:function(n){return u.foreverFrame.connections[n]},started:function(t){t.onSuccess?(t.onSuccess(),t.onSuccess=null,delete t.onSuccess):n(t).trigger(i.onReconnect)}},longPolling:{name:"longPolling",reconnectDelay:3e3,start:function(r,f){var o=this;r.pollXhr&&r.stop(),r.messageId=null,t.setTimeout(function(){(function e(f,s){n(f).trigger(i.onSending);var a=f.messageId,l=a===null,v=u.getUrl(f,o.name,!l),c=null,h=!1;f.pollXhr=n.ajax(v,{global:!1,type:"GET",dataType:"json",success:function(r){var c=0,o=!1;s===!0&&h===!1&&(n(f).trigger(i.onReconnect),h=!0),u.processMessages(f,r),r&&n.type(r.TransportData.LongPollDelay)==="number"&&(c=r.TransportData.LongPollDelay),r&&r.TimedOut&&(o=r.TimedOut),c>0?t.setTimeout(function(){e(f,o)},c):e(f,o)},error:function(u,o){if(o==="abort")return;c&&clearTimeout(c),n(f).trigger(i.onError,[u]),t.setTimeout(function(){e(f,!0)},r.reconnectDelay)}}),s===!0&&(c=t.setTimeout(function(){h===!1&&(n(f).trigger(i.onReconnect),h=!0)},o.reconnectDelay))})(r),t.setTimeout(f,150)},250)},send:function(n,t){u.ajaxSend(n,t)},stop:function(n){n.pollXhr&&(n.pollXhr.abort(),n.pollXhr=null,delete n.pollXhr)}}},f.noConflict=function(){return n.connection===f&&(n.connection=e),f},n.connection&&(e=n.connection),n.connection=n.signalR=f})(window.jQuery,window) \ No newline at end of file diff --git a/SignalR.Hosting.Owin.Samples/Content/Scripts/jquery.signalR.js b/SignalR.Hosting.Owin.Samples/Content/Scripts/jquery.signalR.js index 4b65187638..ad467bc213 100644 --- a/SignalR.Hosting.Owin.Samples/Content/Scripts/jquery.signalR.js +++ b/SignalR.Hosting.Owin.Samples/Content/Scripts/jquery.signalR.js @@ -15,7 +15,19 @@ var signalR, _connection, - log = function (msg) { + events = { + onStart: "onStart", + onStarting: "onStarting", + onSending: "onSending", + onReceived: "onReceived", + onError: "onError", + onReconnect: "onReconnect", + onDisconnect: "onDisconnect" + }, + log = function (msg, logging) { + if (logging === false) { + return; + } var m; if (typeof (window.console) === "undefined") { return; @@ -28,7 +40,7 @@ } }; - signalR = function (url, qs) { + signalR = function (url, qs, logging) { /// Creates a new SignalR connection for the given url /// The URL of the long polling endpoint /// @@ -36,17 +48,26 @@ /// If an object, every non-function member will be added to the querystring. /// If a string, it's added to the QS as specified. /// + /// + /// [Optional] A flag indicating whether connection logging is enabled to the browser + /// console/log. Defaults to false. + /// /// - return new signalR.fn.init(url, qs); + return new signalR.fn.init(url, qs, logging); }; signalR.fn = signalR.prototype = { - init: function (url, qs) { + init: function (url, qs, logging) { this.url = url; this.qs = qs; + if (typeof (logging) === "boolean") { + this.logging = logging; + } }, + logging: false, + reconnectDelay: 2000, start: function (options, callback) { @@ -76,7 +97,7 @@ } } - $(connection).bind("onStart", function (e, data) { + $(connection).bind(events.onStart, function (e, data) { if ($.type(callback) === "function") { callback.call(connection); } @@ -98,7 +119,7 @@ transport.start(connection, function () { connection.transport = transport; - $(connection).trigger("onStart"); + $(connection).trigger(events.onStart); }, function () { initialize(transports, index + 1); }); @@ -109,16 +130,22 @@ global: false, type: "POST", data: {}, + error: function (error) { + $(connection).trigger(events.onError, [error]); + promise.reject("SignalR: Error during negotiation request: " + error); + }, success: function (res) { connection.appRelativeUrl = res.Url; connection.id = res.ConnectionId; connection.webSocketServerUrl = res.WebSocketServerUrl; if (!res.ProtocolVersion || res.ProtocolVersion !== "1.0") { - throw "SignalR: Incompatible protocol version."; + $(connection).trigger(events.onError, "SignalR: Incompatible protocol version."); + promise.reject("SignalR: Incompatible protocol version."); + return; } - $(connection).trigger("onStarting"); + $(connection).trigger(events.onStarting); var transports = [], supportedTransports = []; @@ -161,10 +188,10 @@ var connection = this, $connection = $(connection); - $connection.bind("onStarting", function (e, data) { + $connection.bind(events.onStarting, function (e, data) { callback.call(connection); // Unbind immediately, we don't want to call this callback again - $connection.unbind("onStarting"); + $connection.unbind(events.onStarting); }); return connection; @@ -191,7 +218,7 @@ /// A callback function to execute before each time data is sent on the connection /// var connection = this; - $(connection).bind("onSending", function (e, data) { + $(connection).bind(events.onSending, function (e, data) { callback.call(connection); }); return connection; @@ -202,7 +229,7 @@ /// A callback function to execute when any data is received on the connection /// var connection = this; - $(connection).bind("onReceived", function (e, data) { + $(connection).bind(events.onReceived, function (e, data) { callback.call(connection, data); }); return connection; @@ -213,29 +240,29 @@ /// A callback function to execute when an error occurs on the connection /// var connection = this; - $(connection).bind("onError", function (e, data) { + $(connection).bind(events.onError, function (e, data) { callback.call(connection, data); }); return connection; }, - disconnect: function (callback) { + disconnected: function (callback) { /// Adds a callback that will be invoked when the client disconnects /// A callback function to execute when the connection is broken /// var connection = this; - $(connection).bind("onDisconnect", function (e, data) { + $(connection).bind(events.onDisconnect, function (e, data) { callback.call(connection); }); return connection; }, - reconnect: function (callback) { + reconnected: function (callback) { /// Adds a callback that will be invoked when the underlying transport reconnects /// A callback function to execute when the connection is restored /// var connection = this; - $(connection).bind("onReconnect", function (e, data) { + $(connection).bind(events.onReconnect, function (e, data) { callback.call(connection); }); return connection; @@ -254,6 +281,9 @@ delete connection.messageId; delete connection.groups; + // Trigger the disconnect event + $(connection).trigger(events.onDisconnect); + return connection; }, @@ -318,14 +348,14 @@ }, success: function (result) { if (result) { - $(connection).trigger("onReceived", [result]); + $(connection).trigger(events.onReceived, [result]); } }, error: function (errData, textStatus) { if (textStatus === "abort") { return; } - $(connection).trigger("onError", [errData]); + $(connection).trigger(events.onError, [errData]); } }); }, @@ -335,24 +365,24 @@ if (data) { if (data.Disconnect) { - log("disconnect command received from server"); + log("Disconnect command received from server", connection.logging); // Disconnected by the server connection.stop(); // Trigger the disconnect event - $connection.trigger("onDisconnect"); + $connection.trigger(events.onDisconnect); return; } if (data.Messages) { $.each(data.Messages, function () { try { - $connection.trigger("onReceived", [this]); + $connection.trigger(events.onReceived, [this]); } catch (e) { - log("Error raising received " + e); - $(connection).trigger("onError", [e]); + log("Error raising received " + e, connection.logging); + $(connection).trigger(events.onError, [e]); } }); } @@ -402,7 +432,7 @@ } // Build the url - $(connection).trigger("onSending"); + $(connection).trigger(events.onSending); if (connection.data) { url += "?connectionData=" + connection.data + "&transport=webSockets&connectionId=" + connection.id; } else { @@ -425,7 +455,7 @@ } 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("onError"); + $(connection).trigger(events.onError); // TODO: Support reconnect attempt here, need to ensure last message id, groups, and connection data go up on reconnect } connection.socket = null; @@ -440,14 +470,14 @@ if (data.Messages) { $.each(data.Messages, function () { try { - $connection.trigger("onReceived", [this]); + $connection.trigger(events.onReceived, [this]); } catch (e) { - log("Error raising received " + e); + log("Error raising received " + e, connection.logging); } }); } else { - $connection.trigger("onReceived", [data]); + $connection.trigger(events.onReceived, [data]); } } }; @@ -486,7 +516,7 @@ return; } - $connection.trigger("onSending"); + $connection.trigger(events.onSending); url = transportLogic.getUrl(connection, this.name, reconnecting); @@ -494,16 +524,16 @@ connection.eventSource = new window.EventSource(url); } catch (e) { - log("EventSource failed trying to connect with error " + e.Message); + log("EventSource failed trying to connect with error " + e.Message, connection.logging); if (onFailed) { // The connection failed, call the failed callback onFailed(); } else { - $connection.trigger("onError", [e]); + $connection.trigger(events.onError, [e]); if (reconnecting) { // If we were reconnecting, rather than doing initial connect, then try reconnect again - log("EventSource reconnecting"); + log("EventSource reconnecting", connection.logging); that.reconnect(connection); } } @@ -514,7 +544,7 @@ // and raise on failed connectTimeOut = window.setTimeout(function () { if (opened === false) { - log("EventSource timed out trying to connect"); + log("EventSource timed out trying to connect", connection.logging); if (onFailed) { onFailed(); @@ -522,7 +552,7 @@ if (reconnecting) { // If we were reconnecting, rather than doing initial connect, then try reconnect again - log("EventSource reconnecting"); + log("EventSource reconnecting", connection.logging); that.reconnect(connection); } else { that.stop(connection); @@ -532,7 +562,7 @@ that.timeOut); connection.eventSource.addEventListener("open", function (e) { - log("EventSource connected"); + log("EventSource connected", connection.logging); if (connectTimeOut) { window.clearTimeout(connectTimeOut); @@ -546,7 +576,7 @@ } if (reconnecting) { - $connection.trigger("onReconnect"); + $connection.trigger(events.onReconnect); } } }, false); @@ -567,7 +597,7 @@ return; } - log("EventSource readyState: " + connection.eventSource.readyState); + log("EventSource readyState: " + connection.eventSource.readyState, connection.logging); if (e.eventPhase === window.EventSource.CLOSED) { // connection closed @@ -576,19 +606,19 @@ // 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. - log("EventSource reconnecting due to the server connection ending"); + log("EventSource reconnecting due to the server connection ending", connection.logging); that.reconnect(connection); } else { // The EventSource has closed, either because its close() method was called, // or the server sent down a "don't reconnect" frame. - log("EventSource closed"); + log("EventSource closed", connection.logging); that.stop(connection); } } else { // connection error - log("EventSource error"); - $connection.trigger("onError"); + log("EventSource error", connection.logging); + $connection.trigger(events.onError); } }, false); }, @@ -634,7 +664,7 @@ return; } - $(connection).trigger("onSending"); + $(connection).trigger(events.onSending); // Build the url url = transportLogic.getUrl(connection, this.name); @@ -645,7 +675,7 @@ frame.bind("readystatechange", function () { if ($.inArray(this.readyState, ["loaded", "complete"]) >= 0) { - log("Forever frame iframe readyState changed to " + this.readyState + ", reconnecting"); + log("Forever frame iframe readyState changed to " + this.readyState + ", reconnecting", connection.logging); that.reconnect(connection); } }); @@ -715,7 +745,7 @@ } else { // If there's no onSuccess handler we assume this is a reconnect - $(connection).trigger("onReconnect"); + $(connection).trigger(events.onReconnect); } } }, @@ -723,6 +753,8 @@ longPolling: { name: "longPolling", + reconnectDelay: 3000, + start: function (connection, onSuccess, onFailed) { /// Starts the long polling connection /// The SignalR connection to start @@ -734,18 +766,14 @@ connection.messageId = null; window.setTimeout(function () { - (function poll(instance) { - $(instance).trigger("onSending"); + (function poll(instance, raiseReconnect) { + $(instance).trigger(events.onSending); var messageId = instance.messageId, connect = (messageId === null), - url = transportLogic.getUrl(instance, that.name, !connect); - - if (!connect) { - window.setTimeout(function () { - $(instance).trigger("onReconnect"); - }, 100); - } + url = transportLogic.getUrl(instance, that.name, !connect), + reconnectTimeOut = null, + reconnectFired = false; instance.pollXhr = $.ajax(url, { global: false, @@ -755,17 +783,32 @@ dataType: "json", success: function (data) { - var delay = 0; + var delay = 0, + timedOutReceived = false; + + if (raiseReconnect === true) { + // Fire the reconnect event if it hasn't been fired as yet + if (reconnectFired === false) { + $(instance).trigger(events.onReconnect); + reconnectFired = true; + } + } + transportLogic.processMessages(instance, data); if (data && $.type(data.TransportData.LongPollDelay) === "number") { delay = data.TransportData.LongPollDelay; } + + if (data && data.TimedOut) { + timedOutReceived = data.TimedOut; + } + if (delay > 0) { window.setTimeout(function () { - poll(instance); + poll(instance, timedOutReceived); }, delay); } else { - poll(instance); + poll(instance, timedOutReceived); } }, @@ -774,13 +817,30 @@ return; } - $(instance).trigger("onError", [data]); + if (reconnectTimeOut) { + // If the request failed then we clear the timeout so that the + // reconnect event doesn't get fired + clearTimeout(reconnectTimeOut); + } + + $(instance).trigger(events.onError, [data]); window.setTimeout(function () { - poll(instance); + poll(instance, true); }, connection.reconnectDelay); } }); + + if (raiseReconnect === true) { + reconnectTimeOut = window.setTimeout(function () { + if (reconnectFired === false) { + $(instance).trigger(events.onReconnect); + reconnectFired = true; + } + }, + that.reconnectDelay); + } + } (connection)); // Now connected diff --git a/SignalR.Hosting.Owin.Samples/Content/Scripts/jquery.signalR.min.js b/SignalR.Hosting.Owin.Samples/Content/Scripts/jquery.signalR.min.js index 7467b78a2d..aae488b71d 100644 --- a/SignalR.Hosting.Owin.Samples/Content/Scripts/jquery.signalR.min.js +++ b/SignalR.Hosting.Owin.Samples/Content/Scripts/jquery.signalR.min.js @@ -1 +1 @@ -(function(n,t){"use strict";var u,f,i,r;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.";i=function(n){var i;if(typeof t.console=="undefined")return;i="["+(new Date).toTimeString()+"] SignalR: "+n,t.console.debug?t.console.debug(i):t.console.log&&t.console.log(i)},u=function(n,t){return new u.fn.init(n,t)},u.fn=u.prototype={init:function(n,t){this.url=n,this.qs=t},reconnectDelay:2e3,start:function(i,r){var f=this,e={transport:"auto"},s,o=n.Deferred();return f.transport?(o.resolve(f),o):(n.type(i)==="function"?r=i:n.type(i)==="object"&&(n.extend(e,i),n.type(e.callback)==="function"&&(r=e.callback)),n(f).bind("onStart",function(){n.type(r)==="function"&&r.call(f),o.resolve(f)}),s=function(t,i){i=i||0;if(i>=t.length){f.transport||o.reject("SignalR: No transport could be initialized successfully. Try specifying a different transport or none at all for auto initialization.");return}var r=t[i],e=n.type(r)==="object"?r:u.transports[r];e.start(f,function(){f.transport=e,n(f).trigger("onStart")},function(){s(t,i+1)})},t.setTimeout(function(){n.ajax(f.url+"/negotiate",{global:!1,type:"POST",data:{},success:function(t){f.appRelativeUrl=t.Url,f.id=t.ConnectionId,f.webSocketServerUrl=t.WebSocketServerUrl;if(!t.ProtocolVersion||t.ProtocolVersion!=="1.0")throw"SignalR: Incompatible protocol version.";n(f).trigger("onStarting");var r=[],i=[];n.each(u.transports,function(n){if(n==="webSockets"&&!t.TryWebSockets)return!0;i.push(n)}),n.isArray(e.transport)?n.each(e.transport,function(){var t=this;n.type(t)!=="object"&&(n.type(t)!=="string"||n.inArray(""+t,i)<0)||r.push(n.type(t)==="string"?""+t:t)}):n.type(e.transport)!=="object"&&n.inArray(e.transport,i)<0?r=i:r.push(e.transport),s(r)}})},0),o)},starting:function(t){var i=this,r=n(i);return r.bind("onStarting",function(){t.call(i),r.unbind("onStarting")}),i},send:function(n){var t=this;if(!t.transport)throw"SignalR: Connection must be started before data can be sent. Call .start() before .send()";return t.transport.send(t,n),t},sending:function(t){var i=this;return n(i).bind("onSending",function(){t.call(i)}),i},received:function(t){var i=this;return n(i).bind("onReceived",function(n,r){t.call(i,r)}),i},error:function(t){var i=this;return n(i).bind("onError",function(n,r){t.call(i,r)}),i},disconnect:function(t){var i=this;return n(i).bind("onDisconnect",function(){t.call(i)}),i},reconnect:function(t){var i=this;return n(i).bind("onReconnect",function(){t.call(i)}),i},stop:function(){var n=this;return n.transport&&(n.transport.stop(n),n.transport=null),delete n.messageId,delete n.groups,n},log:i},u.fn.init.prototype=u.fn,r={addQs:function(t,i){return i.qs?typeof i.qs=="object"?t+"&"+n.param(i.qs):typeof i.qs=="string"?t+"&"+i.qs:t+"&"+escape(i.qs.toString()):t},getUrl:function(n,i,r){var u=n.url,f="transport="+i+"&connectionId="+t.escape(n.id);return n.data&&(f+="&connectionData="+t.escape(n.data)),r?(n.messageId&&(f+="&messageId="+n.messageId),n.groups&&(f+="&groups="+t.escape(JSON.stringify(n.groups)))):u=u+"/connect",u+="?"+f,u=this.addQs(u,n)},ajaxSend:function(i,r){var u=i.url+"/send?transport="+i.transport.name+"&connectionId="+t.escape(i.id);u=this.addQs(u,i),n.ajax(u,{global:!1,type:"POST",dataType:"json",data:{data:r},success:function(t){t&&n(i).trigger("onReceived",[t])},error:function(t,r){if(r==="abort")return;n(i).trigger("onError",[t])}})},processMessages:function(t,r){var u=n(t);if(r){if(r.Disconnect){i("disconnect command received from server"),t.stop(),u.trigger("onDisconnect");return}r.Messages&&n.each(r.Messages,function(){try{u.trigger("onReceived",[this])}catch(r){i("Error raising received "+r),n(t).trigger("onError",[r])}}),t.messageId=r.MessageId,t.groups=r.TransportData.Groups}},foreverFrame:{count:0,connections:{}}},u.transports={webSockets:{name:"webSockets",send:function(n,t){n.socket.send(t)},start:function(r,u,f){var e,s=!1,o;t.MozWebSocket&&(t.WebSocket=t.MozWebSocket);if(!t.WebSocket){f();return}r.socket||(r.webSocketServerUrl?e=r.webSocketServerUrl:(o=document.location.protocol==="https:"?"wss://":"ws://",e=o+document.location.host+r.appRelativeUrl),n(r).trigger("onSending"),e+=r.data?"?connectionData="+r.data+"&transport=webSockets&connectionId="+r.id:"?transport=webSockets&connectionId="+r.id,r.socket=new t.WebSocket(e),r.socket.onopen=function(){s=!0,u&&u()},r.socket.onclose=function(t){s?typeof t.wasClean!="undefined"&&t.wasClean===!1&&n(r).trigger("onError"):f&&f(),r.socket=null},r.socket.onmessage=function(u){var f=t.JSON.parse(u.data),e;f&&(e=n(r),f.Messages?n.each(f.Messages,function(){try{e.trigger("onReceived",[this])}catch(n){i("Error raising received "+n)}}):e.trigger("onReceived",[f]))})},stop:function(n){n.socket!==null&&(n.socket.close(),n.socket=null)}},serverSentEvents:{name:"serverSentEvents",timeOut:3e3,start:function(u,f,e){var o=this,c=!1,h=n(u),s=!f,a,l;u.eventSource&&u.stop();if(!t.EventSource){e&&e();return}h.trigger("onSending"),a=r.getUrl(u,this.name,s);try{u.eventSource=new t.EventSource(a)}catch(v){i("EventSource failed trying to connect with error "+v.Message),e?e():(h.trigger("onError",[v]),s&&(i("EventSource reconnecting"),o.reconnect(u)));return}l=t.setTimeout(function(){c===!1&&(i("EventSource timed out trying to connect"),e&&e(),s?(i("EventSource reconnecting"),o.reconnect(u)):o.stop(u))},o.timeOut),u.eventSource.addEventListener("open",function(){i("EventSource connected"),l&&t.clearTimeout(l),c===!1&&(c=!0,f&&f(),s&&h.trigger("onReconnect"))},!1),u.eventSource.addEventListener("message",function(n){if(n.data==="initialized")return;r.processMessages(u,t.JSON.parse(n.data))},!1),u.eventSource.addEventListener("error",function(n){if(!c){e&&e();return}i("EventSource readyState: "+u.eventSource.readyState),n.eventPhase===t.EventSource.CLOSED?u.eventSource.readyState===t.EventSource.CONNECTING?(i("EventSource reconnecting due to the server connection ending"),o.reconnect(u)):(i("EventSource closed"),o.stop(u)):(i("EventSource error"),h.trigger("onError"))},!1)},reconnect:function(n){var i=this;t.setTimeout(function(){i.stop(n),i.start(n)},n.reconnectDelay)},send:function(n,t){r.ajaxSend(n,t)},stop:function(n){n&&n.eventSource&&(n.eventSource.close(),n.eventSource=null,delete n.eventSource)}},foreverFrame:{name:"foreverFrame",timeOut:3e3,start:function(u,f,e){var s=this,c=r.foreverFrame.count+=1,h,l,o=n("");if(t.EventSource){e&&e();return}n(u).trigger("onSending"),h=r.getUrl(u,this.name),h+="&frameId="+c,o.prop("src",h),r.foreverFrame.connections[c]=u,o.bind("readystatechange",function(){n.inArray(this.readyState,["loaded","complete"])<0||(i("Forever frame iframe readyState changed to "+this.readyState+", reconnecting"),s.reconnect(u))}),u.frame=o[0],u.frameId=c,f&&(u.onSuccess=f),n("body").append(o),l=t.setTimeout(function(){u.onSuccess&&(s.stop(u),e&&e())},s.timeOut)},reconnect:function(n){var i=this;t.setTimeout(function(){var u=n.frame,t=r.getUrl(n,i.name,!0)+"&frameId="+n.frameId;u.src=t},n.reconnectDelay)},send:function(n,t){r.ajaxSend(n,t)},receive:r.processMessages,stop:function(t){t.frame&&(t.frame.stop?t.frame.stop():t.frame.document&&t.frame.document.execCommand&&t.frame.document.execCommand("Stop"),n(t.frame).remove(),delete r.foreverFrame.connections[t.frameId],t.frame=null,t.frameId=null,delete t.frame,delete t.frameId)},getConnection:function(n){return r.foreverFrame.connections[n]},started:function(t){t.onSuccess?(t.onSuccess(),t.onSuccess=null,delete t.onSuccess):n(t).trigger("onReconnect")}},longPolling:{name:"longPolling",start:function(i,u){var e=this;i.pollXhr&&i.stop(),i.messageId=null,t.setTimeout(function(){(function f(u){n(u).trigger("onSending");var h=u.messageId,o=h===null,s=r.getUrl(u,e.name,!o);o||t.setTimeout(function(){n(u).trigger("onReconnect")},100),u.pollXhr=n.ajax(s,{global:!1,type:"GET",dataType:"json",success:function(i){var e=0;r.processMessages(u,i),i&&n.type(i.TransportData.LongPollDelay)==="number"&&(e=i.TransportData.LongPollDelay),e>0?t.setTimeout(function(){f(u)},e):f(u)},error:function(r,e){if(e==="abort")return;n(u).trigger("onError",[r]),t.setTimeout(function(){f(u)},i.reconnectDelay)}})})(i),t.setTimeout(u,150)},250)},send:function(n,t){r.ajaxSend(n,t)},stop:function(n){n.pollXhr&&(n.pollXhr.abort(),n.pollXhr=null,delete n.pollXhr)}}},u.noConflict=function(){return n.connection===u&&(n.connection=f),u},n.connection&&(f=n.connection),n.connection=n.signalR=u})(window.jQuery,window) \ No newline at end of file +(function(n,t){"use strict";var f,e,i,r,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.";i={onStart:"onStart",onStarting:"onStarting",onSending:"onSending",onReceived:"onReceived",onError:"onError",onReconnect:"onReconnect",onDisconnect:"onDisconnect"},r=function(n,i){if(i===!1)return;var r;if(typeof t.console=="undefined")return;r="["+(new Date).toTimeString()+"] SignalR: "+n,t.console.debug?t.console.debug(r):t.console.log&&t.console.log(r)},f=function(n,t,i){return new f.fn.init(n,t,i)},f.fn=f.prototype={init:function(n,t,i){this.url=n,this.qs=t,typeof i=="boolean"&&(this.logging=i)},logging:!1,reconnectDelay:2e3,start:function(r,u){var e=this,o={transport:"auto"},h,s=n.Deferred();return e.transport?(s.resolve(e),s):(n.type(r)==="function"?u=r:n.type(r)==="object"&&(n.extend(o,r),n.type(o.callback)==="function"&&(u=o.callback)),n(e).bind(i.onStart,function(){n.type(u)==="function"&&u.call(e),s.resolve(e)}),h=function(t,r){r=r||0;if(r>=t.length){e.transport||s.reject("SignalR: No transport could be initialized successfully. Try specifying a different transport or none at all for auto initialization.");return}var u=t[r],o=n.type(u)==="object"?u:f.transports[u];o.start(e,function(){e.transport=o,n(e).trigger(i.onStart)},function(){h(t,r+1)})},t.setTimeout(function(){n.ajax(e.url+"/negotiate",{global:!1,type:"POST",data:{},error:function(t){n(e).trigger(i.onError,[t]),s.reject("SignalR: Error during negotiation request: "+t)},success:function(t){e.appRelativeUrl=t.Url,e.id=t.ConnectionId,e.webSocketServerUrl=t.WebSocketServerUrl;if(!t.ProtocolVersion||t.ProtocolVersion!=="1.0"){n(e).trigger(i.onError,"SignalR: Incompatible protocol version."),s.reject("SignalR: Incompatible protocol version.");return}n(e).trigger(i.onStarting);var u=[],r=[];n.each(f.transports,function(n){if(n==="webSockets"&&!t.TryWebSockets)return!0;r.push(n)}),n.isArray(o.transport)?n.each(o.transport,function(){var t=this;n.type(t)!=="object"&&(n.type(t)!=="string"||n.inArray(""+t,r)<0)||u.push(n.type(t)==="string"?""+t:t)}):n.type(o.transport)!=="object"&&n.inArray(o.transport,r)<0?u=r:u.push(o.transport),h(u)}})},0),s)},starting:function(t){var r=this,u=n(r);return u.bind(i.onStarting,function(){t.call(r),u.unbind(i.onStarting)}),r},send:function(n){var t=this;if(!t.transport)throw"SignalR: Connection must be started before data can be sent. Call .start() before .send()";return t.transport.send(t,n),t},sending:function(t){var r=this;return n(r).bind(i.onSending,function(){t.call(r)}),r},received:function(t){var r=this;return n(r).bind(i.onReceived,function(n,i){t.call(r,i)}),r},error:function(t){var r=this;return n(r).bind(i.onError,function(n,i){t.call(r,i)}),r},disconnected:function(t){var r=this;return n(r).bind(i.onDisconnect,function(){t.call(r)}),r},reconnected:function(t){var r=this;return n(r).bind(i.onReconnect,function(){t.call(r)}),r},stop:function(){var t=this;return t.transport&&(t.transport.stop(t),t.transport=null),delete t.messageId,delete t.groups,n(t).trigger(i.onDisconnect),t},log:r},f.fn.init.prototype=f.fn,u={addQs:function(t,i){return i.qs?typeof i.qs=="object"?t+"&"+n.param(i.qs):typeof i.qs=="string"?t+"&"+i.qs:t+"&"+escape(i.qs.toString()):t},getUrl:function(n,i,r){var u=n.url,f="transport="+i+"&connectionId="+t.escape(n.id);return n.data&&(f+="&connectionData="+t.escape(n.data)),r?(n.messageId&&(f+="&messageId="+n.messageId),n.groups&&(f+="&groups="+t.escape(JSON.stringify(n.groups)))):u=u+"/connect",u+="?"+f,u=this.addQs(u,n)},ajaxSend:function(r,u){var f=r.url+"/send?transport="+r.transport.name+"&connectionId="+t.escape(r.id);f=this.addQs(f,r),n.ajax(f,{global:!1,type:"POST",dataType:"json",data:{data:u},success:function(t){t&&n(r).trigger(i.onReceived,[t])},error:function(t,u){if(u==="abort")return;n(r).trigger(i.onError,[t])}})},processMessages:function(t,u){var f=n(t);if(u){if(u.Disconnect){r("Disconnect command received from server",t.logging),t.stop(),f.trigger(i.onDisconnect);return}u.Messages&&n.each(u.Messages,function(){try{f.trigger(i.onReceived,[this])}catch(u){r("Error raising received "+u,t.logging),n(t).trigger(i.onError,[u])}}),t.messageId=u.MessageId,t.groups=u.TransportData.Groups}},foreverFrame:{count:0,connections:{}}},f.transports={webSockets:{name:"webSockets",send:function(n,t){n.socket.send(t)},start:function(u,f,e){var o,h=!1,s;t.MozWebSocket&&(t.WebSocket=t.MozWebSocket);if(!t.WebSocket){e();return}u.socket||(u.webSocketServerUrl?o=u.webSocketServerUrl:(s=document.location.protocol==="https:"?"wss://":"ws://",o=s+document.location.host+u.appRelativeUrl),n(u).trigger(i.onSending),o+=u.data?"?connectionData="+u.data+"&transport=webSockets&connectionId="+u.id:"?transport=webSockets&connectionId="+u.id,u.socket=new t.WebSocket(o),u.socket.onopen=function(){h=!0,f&&f()},u.socket.onclose=function(t){h?typeof t.wasClean!="undefined"&&t.wasClean===!1&&n(u).trigger(i.onError):e&&e(),u.socket=null},u.socket.onmessage=function(f){var e=t.JSON.parse(f.data),o;e&&(o=n(u),e.Messages?n.each(e.Messages,function(){try{o.trigger(i.onReceived,[this])}catch(n){r("Error raising received "+n,u.logging)}}):o.trigger(i.onReceived,[e]))})},stop:function(n){n.socket!==null&&(n.socket.close(),n.socket=null)}},serverSentEvents:{name:"serverSentEvents",timeOut:3e3,start:function(f,e,o){var s=this,l=!1,c=n(f),h=!e,v,a;f.eventSource&&f.stop();if(!t.EventSource){o&&o();return}c.trigger(i.onSending),v=u.getUrl(f,this.name,h);try{f.eventSource=new t.EventSource(v)}catch(y){r("EventSource failed trying to connect with error "+y.Message,f.logging),o?o():(c.trigger(i.onError,[y]),h&&(r("EventSource reconnecting",f.logging),s.reconnect(f)));return}a=t.setTimeout(function(){l===!1&&(r("EventSource timed out trying to connect",f.logging),o&&o(),h?(r("EventSource reconnecting",f.logging),s.reconnect(f)):s.stop(f))},s.timeOut),f.eventSource.addEventListener("open",function(){r("EventSource connected",f.logging),a&&t.clearTimeout(a),l===!1&&(l=!0,e&&e(),h&&c.trigger(i.onReconnect))},!1),f.eventSource.addEventListener("message",function(n){if(n.data==="initialized")return;u.processMessages(f,t.JSON.parse(n.data))},!1),f.eventSource.addEventListener("error",function(n){if(!l){o&&o();return}r("EventSource readyState: "+f.eventSource.readyState,f.logging),n.eventPhase===t.EventSource.CLOSED?f.eventSource.readyState===t.EventSource.CONNECTING?(r("EventSource reconnecting due to the server connection ending",f.logging),s.reconnect(f)):(r("EventSource closed",f.logging),s.stop(f)):(r("EventSource error",f.logging),c.trigger(i.onError))},!1)},reconnect:function(n){var i=this;t.setTimeout(function(){i.stop(n),i.start(n)},n.reconnectDelay)},send:function(n,t){u.ajaxSend(n,t)},stop:function(n){n&&n.eventSource&&(n.eventSource.close(),n.eventSource=null,delete n.eventSource)}},foreverFrame:{name:"foreverFrame",timeOut:3e3,start:function(f,e,o){var h=this,l=u.foreverFrame.count+=1,c,a,s=n("");if(t.EventSource){o&&o();return}n(f).trigger(i.onSending),c=u.getUrl(f,this.name),c+="&frameId="+l,s.prop("src",c),u.foreverFrame.connections[l]=f,s.bind("readystatechange",function(){n.inArray(this.readyState,["loaded","complete"])<0||(r("Forever frame iframe readyState changed to "+this.readyState+", reconnecting",f.logging),h.reconnect(f))}),f.frame=s[0],f.frameId=l,e&&(f.onSuccess=e),n("body").append(s),a=t.setTimeout(function(){f.onSuccess&&(h.stop(f),o&&o())},h.timeOut)},reconnect:function(n){var i=this;t.setTimeout(function(){var r=n.frame,t=u.getUrl(n,i.name,!0)+"&frameId="+n.frameId;r.src=t},n.reconnectDelay)},send:function(n,t){u.ajaxSend(n,t)},receive:u.processMessages,stop:function(t){t.frame&&(t.frame.stop?t.frame.stop():t.frame.document&&t.frame.document.execCommand&&t.frame.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)},getConnection:function(n){return u.foreverFrame.connections[n]},started:function(t){t.onSuccess?(t.onSuccess(),t.onSuccess=null,delete t.onSuccess):n(t).trigger(i.onReconnect)}},longPolling:{name:"longPolling",reconnectDelay:3e3,start:function(r,f){var o=this;r.pollXhr&&r.stop(),r.messageId=null,t.setTimeout(function(){(function e(f,s){n(f).trigger(i.onSending);var a=f.messageId,l=a===null,v=u.getUrl(f,o.name,!l),c=null,h=!1;f.pollXhr=n.ajax(v,{global:!1,type:"GET",dataType:"json",success:function(r){var c=0,o=!1;s===!0&&h===!1&&(n(f).trigger(i.onReconnect),h=!0),u.processMessages(f,r),r&&n.type(r.TransportData.LongPollDelay)==="number"&&(c=r.TransportData.LongPollDelay),r&&r.TimedOut&&(o=r.TimedOut),c>0?t.setTimeout(function(){e(f,o)},c):e(f,o)},error:function(u,o){if(o==="abort")return;c&&clearTimeout(c),n(f).trigger(i.onError,[u]),t.setTimeout(function(){e(f,!0)},r.reconnectDelay)}}),s===!0&&(c=t.setTimeout(function(){h===!1&&(n(f).trigger(i.onReconnect),h=!0)},o.reconnectDelay))})(r),t.setTimeout(f,150)},250)},send:function(n,t){u.ajaxSend(n,t)},stop:function(n){n.pollXhr&&(n.pollXhr.abort(),n.pollXhr=null,delete n.pollXhr)}}},f.noConflict=function(){return n.connection===f&&(n.connection=e),f},n.connection&&(e=n.connection),n.connection=n.signalR=f})(window.jQuery,window) \ No newline at end of file diff --git a/SignalR.Hosting.Owin.Samples/SignalR.Hosting.Owin.Samples.csproj b/SignalR.Hosting.Owin.Samples/SignalR.Hosting.Owin.Samples.csproj index 45f45cf149..b69e6e2dfc 100644 --- a/SignalR.Hosting.Owin.Samples/SignalR.Hosting.Owin.Samples.csproj +++ b/SignalR.Hosting.Owin.Samples/SignalR.Hosting.Owin.Samples.csproj @@ -210,11 +210,8 @@ - + + + + \ No newline at end of file diff --git a/SignalR.Hosting.Owin/SignalR.Hosting.Owin.csproj b/SignalR.Hosting.Owin/SignalR.Hosting.Owin.csproj index dee88401a5..193b8c2924 100644 --- a/SignalR.Hosting.Owin/SignalR.Hosting.Owin.csproj +++ b/SignalR.Hosting.Owin/SignalR.Hosting.Owin.csproj @@ -74,11 +74,4 @@ - \ No newline at end of file diff --git a/SignalR/Scripts/jquery.signalR.js b/SignalR/Scripts/jquery.signalR.js index c877e05772..ad467bc213 100644 --- a/SignalR/Scripts/jquery.signalR.js +++ b/SignalR/Scripts/jquery.signalR.js @@ -282,7 +282,7 @@ delete connection.groups; // Trigger the disconnect event - $connection.trigger(events.onDisconnect); + $(connection).trigger(events.onDisconnect); return connection; }, diff --git a/SignalR/Scripts/jquery.signalR.min.js b/SignalR/Scripts/jquery.signalR.min.js index 9e99f53a38..aae488b71d 100644 --- a/SignalR/Scripts/jquery.signalR.min.js +++ b/SignalR/Scripts/jquery.signalR.min.js @@ -1 +1 @@ -(function(n,t){"use strict";var f,e,i,r,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.";i={onStart:"onStart",onStarting:"onStarting",onSending:"onSending",onReceived:"onReceived",onError:"onError",onReconnect:"onReconnect",onDisconnect:"onDisconnect"},r=function(n,i){if(i===!1)return;var r;if(typeof t.console=="undefined")return;r="["+(new Date).toTimeString()+"] SignalR: "+n,t.console.debug?t.console.debug(r):t.console.log&&t.console.log(r)},f=function(n,t,i){return new f.fn.init(n,t,i)},f.fn=f.prototype={init:function(n,t,i){this.url=n,this.qs=t,typeof i=="boolean"&&(this.logging=i)},logging:!1,reconnectDelay:2e3,start:function(r,u){var e=this,o={transport:"auto"},h,s=n.Deferred();return e.transport?(s.resolve(e),s):(n.type(r)==="function"?u=r:n.type(r)==="object"&&(n.extend(o,r),n.type(o.callback)==="function"&&(u=o.callback)),n(e).bind(i.onStart,function(){n.type(u)==="function"&&u.call(e),s.resolve(e)}),h=function(t,r){r=r||0;if(r>=t.length){e.transport||s.reject("SignalR: No transport could be initialized successfully. Try specifying a different transport or none at all for auto initialization.");return}var u=t[r],o=n.type(u)==="object"?u:f.transports[u];o.start(e,function(){e.transport=o,n(e).trigger(i.onStart)},function(){h(t,r+1)})},t.setTimeout(function(){n.ajax(e.url+"/negotiate",{global:!1,type:"POST",data:{},error:function(t){n(e).trigger(i.onError,[t]),s.reject("SignalR: Error during negotiation request: "+t)},success:function(t){e.appRelativeUrl=t.Url,e.id=t.ConnectionId,e.webSocketServerUrl=t.WebSocketServerUrl;if(!t.ProtocolVersion||t.ProtocolVersion!=="1.0"){n(e).trigger(i.onError,"SignalR: Incompatible protocol version."),s.reject("SignalR: Incompatible protocol version.");return}n(e).trigger(i.onStarting);var u=[],r=[];n.each(f.transports,function(n){if(n==="webSockets"&&!t.TryWebSockets)return!0;r.push(n)}),n.isArray(o.transport)?n.each(o.transport,function(){var t=this;n.type(t)!=="object"&&(n.type(t)!=="string"||n.inArray(""+t,r)<0)||u.push(n.type(t)==="string"?""+t:t)}):n.type(o.transport)!=="object"&&n.inArray(o.transport,r)<0?u=r:u.push(o.transport),h(u)}})},0),s)},starting:function(t){var r=this,u=n(r);return u.bind(i.onStarting,function(){t.call(r),u.unbind(i.onStarting)}),r},send:function(n){var t=this;if(!t.transport)throw"SignalR: Connection must be started before data can be sent. Call .start() before .send()";return t.transport.send(t,n),t},sending:function(t){var r=this;return n(r).bind(i.onSending,function(){t.call(r)}),r},received:function(t){var r=this;return n(r).bind(i.onReceived,function(n,i){t.call(r,i)}),r},error:function(t){var r=this;return n(r).bind(i.onError,function(n,i){t.call(r,i)}),r},disconnected:function(t){var r=this;return n(r).bind(i.onDisconnect,function(){t.call(r)}),r},reconnected:function(t){var r=this;return n(r).bind(i.onReconnect,function(){t.call(r)}),r},stop:function(){var n=this;return n.transport&&(n.transport.stop(n),n.transport=null),delete n.messageId,delete n.groups,$connection.trigger(i.onDisconnect),n},log:r},f.fn.init.prototype=f.fn,u={addQs:function(t,i){return i.qs?typeof i.qs=="object"?t+"&"+n.param(i.qs):typeof i.qs=="string"?t+"&"+i.qs:t+"&"+escape(i.qs.toString()):t},getUrl:function(n,i,r){var u=n.url,f="transport="+i+"&connectionId="+t.escape(n.id);return n.data&&(f+="&connectionData="+t.escape(n.data)),r?(n.messageId&&(f+="&messageId="+n.messageId),n.groups&&(f+="&groups="+t.escape(JSON.stringify(n.groups)))):u=u+"/connect",u+="?"+f,u=this.addQs(u,n)},ajaxSend:function(r,u){var f=r.url+"/send?transport="+r.transport.name+"&connectionId="+t.escape(r.id);f=this.addQs(f,r),n.ajax(f,{global:!1,type:"POST",dataType:"json",data:{data:u},success:function(t){t&&n(r).trigger(i.onReceived,[t])},error:function(t,u){if(u==="abort")return;n(r).trigger(i.onError,[t])}})},processMessages:function(t,u){var f=n(t);if(u){if(u.Disconnect){r("Disconnect command received from server",t.logging),t.stop(),f.trigger(i.onDisconnect);return}u.Messages&&n.each(u.Messages,function(){try{f.trigger(i.onReceived,[this])}catch(u){r("Error raising received "+u,t.logging),n(t).trigger(i.onError,[u])}}),t.messageId=u.MessageId,t.groups=u.TransportData.Groups}},foreverFrame:{count:0,connections:{}}},f.transports={webSockets:{name:"webSockets",send:function(n,t){n.socket.send(t)},start:function(u,f,e){var o,h=!1,s;t.MozWebSocket&&(t.WebSocket=t.MozWebSocket);if(!t.WebSocket){e();return}u.socket||(u.webSocketServerUrl?o=u.webSocketServerUrl:(s=document.location.protocol==="https:"?"wss://":"ws://",o=s+document.location.host+u.appRelativeUrl),n(u).trigger(i.onSending),o+=u.data?"?connectionData="+u.data+"&transport=webSockets&connectionId="+u.id:"?transport=webSockets&connectionId="+u.id,u.socket=new t.WebSocket(o),u.socket.onopen=function(){h=!0,f&&f()},u.socket.onclose=function(t){h?typeof t.wasClean!="undefined"&&t.wasClean===!1&&n(u).trigger(i.onError):e&&e(),u.socket=null},u.socket.onmessage=function(f){var e=t.JSON.parse(f.data),o;e&&(o=n(u),e.Messages?n.each(e.Messages,function(){try{o.trigger(i.onReceived,[this])}catch(n){r("Error raising received "+n,u.logging)}}):o.trigger(i.onReceived,[e]))})},stop:function(n){n.socket!==null&&(n.socket.close(),n.socket=null)}},serverSentEvents:{name:"serverSentEvents",timeOut:3e3,start:function(f,e,o){var s=this,l=!1,c=n(f),h=!e,v,a;f.eventSource&&f.stop();if(!t.EventSource){o&&o();return}c.trigger(i.onSending),v=u.getUrl(f,this.name,h);try{f.eventSource=new t.EventSource(v)}catch(y){r("EventSource failed trying to connect with error "+y.Message,f.logging),o?o():(c.trigger(i.onError,[y]),h&&(r("EventSource reconnecting",f.logging),s.reconnect(f)));return}a=t.setTimeout(function(){l===!1&&(r("EventSource timed out trying to connect",f.logging),o&&o(),h?(r("EventSource reconnecting",f.logging),s.reconnect(f)):s.stop(f))},s.timeOut),f.eventSource.addEventListener("open",function(){r("EventSource connected",f.logging),a&&t.clearTimeout(a),l===!1&&(l=!0,e&&e(),h&&c.trigger(i.onReconnect))},!1),f.eventSource.addEventListener("message",function(n){if(n.data==="initialized")return;u.processMessages(f,t.JSON.parse(n.data))},!1),f.eventSource.addEventListener("error",function(n){if(!l){o&&o();return}r("EventSource readyState: "+f.eventSource.readyState,f.logging),n.eventPhase===t.EventSource.CLOSED?f.eventSource.readyState===t.EventSource.CONNECTING?(r("EventSource reconnecting due to the server connection ending",f.logging),s.reconnect(f)):(r("EventSource closed",f.logging),s.stop(f)):(r("EventSource error",f.logging),c.trigger(i.onError))},!1)},reconnect:function(n){var i=this;t.setTimeout(function(){i.stop(n),i.start(n)},n.reconnectDelay)},send:function(n,t){u.ajaxSend(n,t)},stop:function(n){n&&n.eventSource&&(n.eventSource.close(),n.eventSource=null,delete n.eventSource)}},foreverFrame:{name:"foreverFrame",timeOut:3e3,start:function(f,e,o){var h=this,l=u.foreverFrame.count+=1,c,a,s=n("");if(t.EventSource){o&&o();return}n(f).trigger(i.onSending),c=u.getUrl(f,this.name),c+="&frameId="+l,s.prop("src",c),u.foreverFrame.connections[l]=f,s.bind("readystatechange",function(){n.inArray(this.readyState,["loaded","complete"])<0||(r("Forever frame iframe readyState changed to "+this.readyState+", reconnecting",f.logging),h.reconnect(f))}),f.frame=s[0],f.frameId=l,e&&(f.onSuccess=e),n("body").append(s),a=t.setTimeout(function(){f.onSuccess&&(h.stop(f),o&&o())},h.timeOut)},reconnect:function(n){var i=this;t.setTimeout(function(){var r=n.frame,t=u.getUrl(n,i.name,!0)+"&frameId="+n.frameId;r.src=t},n.reconnectDelay)},send:function(n,t){u.ajaxSend(n,t)},receive:u.processMessages,stop:function(t){t.frame&&(t.frame.stop?t.frame.stop():t.frame.document&&t.frame.document.execCommand&&t.frame.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)},getConnection:function(n){return u.foreverFrame.connections[n]},started:function(t){t.onSuccess?(t.onSuccess(),t.onSuccess=null,delete t.onSuccess):n(t).trigger(i.onReconnect)}},longPolling:{name:"longPolling",reconnectDelay:3e3,start:function(r,f){var o=this;r.pollXhr&&r.stop(),r.messageId=null,t.setTimeout(function(){(function e(f,s){n(f).trigger(i.onSending);var a=f.messageId,l=a===null,v=u.getUrl(f,o.name,!l),c=null,h=!1;f.pollXhr=n.ajax(v,{global:!1,type:"GET",dataType:"json",success:function(r){var c=0,o=!1;s===!0&&h===!1&&(n(f).trigger(i.onReconnect),h=!0),u.processMessages(f,r),r&&n.type(r.TransportData.LongPollDelay)==="number"&&(c=r.TransportData.LongPollDelay),r&&r.TimedOut&&(o=r.TimedOut),c>0?t.setTimeout(function(){e(f,o)},c):e(f,o)},error:function(u,o){if(o==="abort")return;c&&clearTimeout(c),n(f).trigger(i.onError,[u]),t.setTimeout(function(){e(f,!0)},r.reconnectDelay)}}),s===!0&&(c=t.setTimeout(function(){h===!1&&(n(f).trigger(i.onReconnect),h=!0)},o.reconnectDelay))})(r),t.setTimeout(f,150)},250)},send:function(n,t){u.ajaxSend(n,t)},stop:function(n){n.pollXhr&&(n.pollXhr.abort(),n.pollXhr=null,delete n.pollXhr)}}},f.noConflict=function(){return n.connection===f&&(n.connection=e),f},n.connection&&(e=n.connection),n.connection=n.signalR=f})(window.jQuery,window) \ No newline at end of file +(function(n,t){"use strict";var f,e,i,r,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.";i={onStart:"onStart",onStarting:"onStarting",onSending:"onSending",onReceived:"onReceived",onError:"onError",onReconnect:"onReconnect",onDisconnect:"onDisconnect"},r=function(n,i){if(i===!1)return;var r;if(typeof t.console=="undefined")return;r="["+(new Date).toTimeString()+"] SignalR: "+n,t.console.debug?t.console.debug(r):t.console.log&&t.console.log(r)},f=function(n,t,i){return new f.fn.init(n,t,i)},f.fn=f.prototype={init:function(n,t,i){this.url=n,this.qs=t,typeof i=="boolean"&&(this.logging=i)},logging:!1,reconnectDelay:2e3,start:function(r,u){var e=this,o={transport:"auto"},h,s=n.Deferred();return e.transport?(s.resolve(e),s):(n.type(r)==="function"?u=r:n.type(r)==="object"&&(n.extend(o,r),n.type(o.callback)==="function"&&(u=o.callback)),n(e).bind(i.onStart,function(){n.type(u)==="function"&&u.call(e),s.resolve(e)}),h=function(t,r){r=r||0;if(r>=t.length){e.transport||s.reject("SignalR: No transport could be initialized successfully. Try specifying a different transport or none at all for auto initialization.");return}var u=t[r],o=n.type(u)==="object"?u:f.transports[u];o.start(e,function(){e.transport=o,n(e).trigger(i.onStart)},function(){h(t,r+1)})},t.setTimeout(function(){n.ajax(e.url+"/negotiate",{global:!1,type:"POST",data:{},error:function(t){n(e).trigger(i.onError,[t]),s.reject("SignalR: Error during negotiation request: "+t)},success:function(t){e.appRelativeUrl=t.Url,e.id=t.ConnectionId,e.webSocketServerUrl=t.WebSocketServerUrl;if(!t.ProtocolVersion||t.ProtocolVersion!=="1.0"){n(e).trigger(i.onError,"SignalR: Incompatible protocol version."),s.reject("SignalR: Incompatible protocol version.");return}n(e).trigger(i.onStarting);var u=[],r=[];n.each(f.transports,function(n){if(n==="webSockets"&&!t.TryWebSockets)return!0;r.push(n)}),n.isArray(o.transport)?n.each(o.transport,function(){var t=this;n.type(t)!=="object"&&(n.type(t)!=="string"||n.inArray(""+t,r)<0)||u.push(n.type(t)==="string"?""+t:t)}):n.type(o.transport)!=="object"&&n.inArray(o.transport,r)<0?u=r:u.push(o.transport),h(u)}})},0),s)},starting:function(t){var r=this,u=n(r);return u.bind(i.onStarting,function(){t.call(r),u.unbind(i.onStarting)}),r},send:function(n){var t=this;if(!t.transport)throw"SignalR: Connection must be started before data can be sent. Call .start() before .send()";return t.transport.send(t,n),t},sending:function(t){var r=this;return n(r).bind(i.onSending,function(){t.call(r)}),r},received:function(t){var r=this;return n(r).bind(i.onReceived,function(n,i){t.call(r,i)}),r},error:function(t){var r=this;return n(r).bind(i.onError,function(n,i){t.call(r,i)}),r},disconnected:function(t){var r=this;return n(r).bind(i.onDisconnect,function(){t.call(r)}),r},reconnected:function(t){var r=this;return n(r).bind(i.onReconnect,function(){t.call(r)}),r},stop:function(){var t=this;return t.transport&&(t.transport.stop(t),t.transport=null),delete t.messageId,delete t.groups,n(t).trigger(i.onDisconnect),t},log:r},f.fn.init.prototype=f.fn,u={addQs:function(t,i){return i.qs?typeof i.qs=="object"?t+"&"+n.param(i.qs):typeof i.qs=="string"?t+"&"+i.qs:t+"&"+escape(i.qs.toString()):t},getUrl:function(n,i,r){var u=n.url,f="transport="+i+"&connectionId="+t.escape(n.id);return n.data&&(f+="&connectionData="+t.escape(n.data)),r?(n.messageId&&(f+="&messageId="+n.messageId),n.groups&&(f+="&groups="+t.escape(JSON.stringify(n.groups)))):u=u+"/connect",u+="?"+f,u=this.addQs(u,n)},ajaxSend:function(r,u){var f=r.url+"/send?transport="+r.transport.name+"&connectionId="+t.escape(r.id);f=this.addQs(f,r),n.ajax(f,{global:!1,type:"POST",dataType:"json",data:{data:u},success:function(t){t&&n(r).trigger(i.onReceived,[t])},error:function(t,u){if(u==="abort")return;n(r).trigger(i.onError,[t])}})},processMessages:function(t,u){var f=n(t);if(u){if(u.Disconnect){r("Disconnect command received from server",t.logging),t.stop(),f.trigger(i.onDisconnect);return}u.Messages&&n.each(u.Messages,function(){try{f.trigger(i.onReceived,[this])}catch(u){r("Error raising received "+u,t.logging),n(t).trigger(i.onError,[u])}}),t.messageId=u.MessageId,t.groups=u.TransportData.Groups}},foreverFrame:{count:0,connections:{}}},f.transports={webSockets:{name:"webSockets",send:function(n,t){n.socket.send(t)},start:function(u,f,e){var o,h=!1,s;t.MozWebSocket&&(t.WebSocket=t.MozWebSocket);if(!t.WebSocket){e();return}u.socket||(u.webSocketServerUrl?o=u.webSocketServerUrl:(s=document.location.protocol==="https:"?"wss://":"ws://",o=s+document.location.host+u.appRelativeUrl),n(u).trigger(i.onSending),o+=u.data?"?connectionData="+u.data+"&transport=webSockets&connectionId="+u.id:"?transport=webSockets&connectionId="+u.id,u.socket=new t.WebSocket(o),u.socket.onopen=function(){h=!0,f&&f()},u.socket.onclose=function(t){h?typeof t.wasClean!="undefined"&&t.wasClean===!1&&n(u).trigger(i.onError):e&&e(),u.socket=null},u.socket.onmessage=function(f){var e=t.JSON.parse(f.data),o;e&&(o=n(u),e.Messages?n.each(e.Messages,function(){try{o.trigger(i.onReceived,[this])}catch(n){r("Error raising received "+n,u.logging)}}):o.trigger(i.onReceived,[e]))})},stop:function(n){n.socket!==null&&(n.socket.close(),n.socket=null)}},serverSentEvents:{name:"serverSentEvents",timeOut:3e3,start:function(f,e,o){var s=this,l=!1,c=n(f),h=!e,v,a;f.eventSource&&f.stop();if(!t.EventSource){o&&o();return}c.trigger(i.onSending),v=u.getUrl(f,this.name,h);try{f.eventSource=new t.EventSource(v)}catch(y){r("EventSource failed trying to connect with error "+y.Message,f.logging),o?o():(c.trigger(i.onError,[y]),h&&(r("EventSource reconnecting",f.logging),s.reconnect(f)));return}a=t.setTimeout(function(){l===!1&&(r("EventSource timed out trying to connect",f.logging),o&&o(),h?(r("EventSource reconnecting",f.logging),s.reconnect(f)):s.stop(f))},s.timeOut),f.eventSource.addEventListener("open",function(){r("EventSource connected",f.logging),a&&t.clearTimeout(a),l===!1&&(l=!0,e&&e(),h&&c.trigger(i.onReconnect))},!1),f.eventSource.addEventListener("message",function(n){if(n.data==="initialized")return;u.processMessages(f,t.JSON.parse(n.data))},!1),f.eventSource.addEventListener("error",function(n){if(!l){o&&o();return}r("EventSource readyState: "+f.eventSource.readyState,f.logging),n.eventPhase===t.EventSource.CLOSED?f.eventSource.readyState===t.EventSource.CONNECTING?(r("EventSource reconnecting due to the server connection ending",f.logging),s.reconnect(f)):(r("EventSource closed",f.logging),s.stop(f)):(r("EventSource error",f.logging),c.trigger(i.onError))},!1)},reconnect:function(n){var i=this;t.setTimeout(function(){i.stop(n),i.start(n)},n.reconnectDelay)},send:function(n,t){u.ajaxSend(n,t)},stop:function(n){n&&n.eventSource&&(n.eventSource.close(),n.eventSource=null,delete n.eventSource)}},foreverFrame:{name:"foreverFrame",timeOut:3e3,start:function(f,e,o){var h=this,l=u.foreverFrame.count+=1,c,a,s=n("");if(t.EventSource){o&&o();return}n(f).trigger(i.onSending),c=u.getUrl(f,this.name),c+="&frameId="+l,s.prop("src",c),u.foreverFrame.connections[l]=f,s.bind("readystatechange",function(){n.inArray(this.readyState,["loaded","complete"])<0||(r("Forever frame iframe readyState changed to "+this.readyState+", reconnecting",f.logging),h.reconnect(f))}),f.frame=s[0],f.frameId=l,e&&(f.onSuccess=e),n("body").append(s),a=t.setTimeout(function(){f.onSuccess&&(h.stop(f),o&&o())},h.timeOut)},reconnect:function(n){var i=this;t.setTimeout(function(){var r=n.frame,t=u.getUrl(n,i.name,!0)+"&frameId="+n.frameId;r.src=t},n.reconnectDelay)},send:function(n,t){u.ajaxSend(n,t)},receive:u.processMessages,stop:function(t){t.frame&&(t.frame.stop?t.frame.stop():t.frame.document&&t.frame.document.execCommand&&t.frame.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)},getConnection:function(n){return u.foreverFrame.connections[n]},started:function(t){t.onSuccess?(t.onSuccess(),t.onSuccess=null,delete t.onSuccess):n(t).trigger(i.onReconnect)}},longPolling:{name:"longPolling",reconnectDelay:3e3,start:function(r,f){var o=this;r.pollXhr&&r.stop(),r.messageId=null,t.setTimeout(function(){(function e(f,s){n(f).trigger(i.onSending);var a=f.messageId,l=a===null,v=u.getUrl(f,o.name,!l),c=null,h=!1;f.pollXhr=n.ajax(v,{global:!1,type:"GET",dataType:"json",success:function(r){var c=0,o=!1;s===!0&&h===!1&&(n(f).trigger(i.onReconnect),h=!0),u.processMessages(f,r),r&&n.type(r.TransportData.LongPollDelay)==="number"&&(c=r.TransportData.LongPollDelay),r&&r.TimedOut&&(o=r.TimedOut),c>0?t.setTimeout(function(){e(f,o)},c):e(f,o)},error:function(u,o){if(o==="abort")return;c&&clearTimeout(c),n(f).trigger(i.onError,[u]),t.setTimeout(function(){e(f,!0)},r.reconnectDelay)}}),s===!0&&(c=t.setTimeout(function(){h===!1&&(n(f).trigger(i.onReconnect),h=!0)},o.reconnectDelay))})(r),t.setTimeout(f,150)},250)},send:function(n,t){u.ajaxSend(n,t)},stop:function(n){n.pollXhr&&(n.pollXhr.abort(),n.pollXhr=null,delete n.pollXhr)}}},f.noConflict=function(){return n.connection===f&&(n.connection=e),f},n.connection&&(e=n.connection),n.connection=n.signalR=f})(window.jQuery,window) \ No newline at end of file