Click here to Skip to main content
15,881,882 members
Articles / Web Development / HTML

Online Whiteboard using HTML5 and SignalR

Rate me:
Please Sign up or sign in to vote.
4.81/5 (23 votes)
5 Jan 2013CPOL3 min read 131.6K   5.7K   48  
A whiteboard you can instantly share with others and all can start drawing and watching together in real-time
/*!
 * ASP.NET SignalR JavaScript Library v1.0.0
 * http://signalr.net/
 *
 * Copyright Microsoft Open Technologies, Inc. All rights reserved.
 * Licensed under the Apache 2.0
 * https://github.com/SignalR/SignalR/blob/master/LICENSE.md
 *
 */
(function(n,t){"use strict";function s(t,r){var u,f;if(n.isArray(t)){for(u=t.length-1;u>=0;u--)f=t[u],n.type(t)==="object"||n.type(f)==="string"&&i.transports[f]||(r.log("Invalid transport: "+f+", removing it from the transports list."),t.splice(u,1));t.length===0&&(r.log("No transports remain within the specified transport array."),t=null)}else n.type(t)==="object"||i.transports[t]||t==="auto"||(r.log("Invalid transport: "+t.toString()),t=null);return t}if(typeof n!="function")throw new Error("SignalR: jQuery not found. Please ensure jQuery is referenced before the SignalR.js file.");if(!t.JSON)throw new Error("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,e=t.document.readyState==="complete",f=n(t),r={onStart:"onStart",onStarting:"onStarting",onReceived:"onReceived",onError:"onError",onConnectionSlow:"onConnectionSlow",onReconnecting:"onReconnecting",onReconnect:"onReconnect",onStateChanged:"onStateChanged",onDisconnect:"onDisconnect"},l=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))}},a=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?(t.state=u,n(t).triggerHandler(r.onStateChanged,[{oldState:i,newState:u}]),!0):!1},c=function(n){return n.state===i.connectionState.disconnected},h=function(n){var r,u=function(n){n.log("Couldn't reconnect within the configured timeout ("+n.disconnectTimeout+"ms), disconnecting."),n.stop(!1,!1)};n.reconnecting(function(){var n=this;r=t.setTimeout(function(){u(n)},n.disconnectTimeout)}),n.stateChanged(function(n){n.oldState===i.connectionState.reconnecting&&t.clearTimeout(r)})};i=function(n,t,r){return new i.fn.init(n,t,r)},i.events=r,i.changeState=u,i.isDisconnecting=c,i.connectionState={connecting:0,connected:1,reconnecting:2,disconnected:4},i.hub={start:function(){throw new Error("SignalR: Error loading hubs. Ensure your hubs reference is correct, e.g. <script src='/signalr/hubs'><\/script>.");}},f.load(function(){e=!0}),i.fn=i.prototype={init:function(n,t,i){this.url=n,this.qs=t,typeof i=="boolean"&&(this.logging=i),h(this)},ajaxDataType:"json",logging:!1,state:i.connectionState.disconnected,groups:{},keepAliveData:{},reconnectDelay:2e3,disconnectTimeout:4e4,keepAliveTimeoutCount:2,keepAliveWarnAt:2/3,start:function(o,h){var c=this,l={waitForPageLoad:!0,transport:"auto",jsonp:!1},p,v=c._deferral||n.Deferred(),y=t.document.createElement("a"),w;if(n.type(o)==="function"?h=o:n.type(o)==="object"&&(n.extend(l,o),n.type(l.callback)==="function"&&(h=l.callback)),l.transport=s(l.transport,c),!l.transport)throw new Error("SignalR: Invalid transport(s) specified, aborting start.");return!e&&l.waitForPageLoad===!0?(f.load(function(){c._deferral=v,c.start(o,h)}),v.promise()):u(c,i.connectionState.disconnected,i.connectionState.connecting)===!1?(v.resolve(c),v.promise()):(y.href=c.url,y.protocol&&y.protocol!==":"?(c.protocol=y.protocol,c.host=y.host,c.baseUrl=y.protocol+"//"+y.host):(c.protocol=t.document.location.protocol,c.host=t.document.location.host,c.baseUrl=c.protocol+"//"+c.host),c.wsProtocol=c.protocol==="https:"?"wss://":"ws://",l.transport==="auto"&&l.jsonp===!0&&(l.transport="longPolling"),a(c.url)&&(c.log("Auto detected cross domain url."),l.transport==="auto"&&(l.transport=["webSockets","longPolling"]),l.jsonp||(l.jsonp=!n.support.cors,l.jsonp&&c.log("Using jsonp because this browser doesn't support CORS"))),c.ajaxDataType=l.jsonp?"jsonp":"json",n(c).bind(r.onStart,function(){n.type(h)==="function"&&h.call(c),v.resolve(c)}),p=function(t,e){if(e=e||0,e>=t.length){c.transport||(n(c).triggerHandler(r.onError,"SignalR: No transport could be initialized successfully. Try specifying a different transport or none at all for auto initialization."),v.reject("SignalR: No transport could be initialized successfully. Try specifying a different transport or none at all for auto initialization."),c.stop());return}var o=t[e],s=n.type(o)==="object"?o:i.transports[o];if(o.indexOf("_")===0){p(t,e+1);return}s.start(c,function(){s.supportsKeepAlive&&c.keepAliveData.activated&&i.transports._logic.monitorKeepAlive(c),c.transport=s,u(c,i.connectionState.connecting,i.connectionState.connected),n(c).triggerHandler(r.onStart),f.unload(function(){c.stop(!1)})},function(){p(t,e+1)})},w=c.url+"/negotiate",c.log("Negotiating with '"+w+"'."),n.ajax({url:w,global:!1,cache:!1,type:"GET",data:{},dataType:c.ajaxDataType,error:function(t){n(c).triggerHandler(r.onError,[t.responseText]),v.reject("SignalR: Error during negotiation request: "+t.responseText),c.stop()},success:function(t){var u=c.keepAliveData,e,f;if(c.appRelativeUrl=t.Url,c.id=t.ConnectionId,c.webSocketServerUrl=t.WebSocketServerUrl,c.disconnectTimeout=t.DisconnectTimeout*1e3,t.KeepAlive?(t.KeepAlive*=1e3,u.activated=!0,u.timeout=t.KeepAlive*c.keepAliveTimeoutCount,u.timeoutWarning=u.timeout*c.keepAliveWarnAt,u.checkInterval=(u.timeout-u.timeoutWarning)/3):u.activated=!1,!t.ProtocolVersion||t.ProtocolVersion!=="1.1"){n(c).triggerHandler(r.onError,"SignalR: Incompatible protocol version."),v.reject("SignalR: Incompatible protocol version.");return}n(c).triggerHandler(r.onStarting),e=[],f=[],n.each(i.transports,function(n){if(n==="webSockets"&&!t.TryWebSockets)return!0;f.push(n)}),n.isArray(l.transport)?n.each(l.transport,function(){var t=this;(n.type(t)==="object"||n.type(t)==="string"&&n.inArray(""+t,f)>=0)&&e.push(n.type(t)==="string"?""+t:t)}):n.type(l.transport)==="object"||n.inArray(l.transport,f)>=0?e.push(l.transport):e=f,p(e)}}),v.promise())},starting:function(t){var i=this;return n(i).bind(r.onStarting,function(){t.call(i)}),i},send:function(n){var t=this;if(t.state===i.connectionState.disconnected)throw new Error("SignalR: Connection must be started before data can be sent. Call .start() before .send()");if(t.state===i.connectionState.connecting)throw new Error("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},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},connectionSlow:function(t){var i=this;return n(i).bind(r.onConnectionSlow,function(){t.call(i)}),i},reconnecting:function(t){var i=this;return n(i).bind(r.onReconnecting,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,f){var e=this;if(e.state!==i.connectionState.disconnected){try{e.transport&&(f!==!1&&e.transport.abort(e,t),e.transport.supportsKeepAlive&&e.keepAliveData.activated&&i.transports._logic.stopMonitoringKeepAlive(e),e.transport.stop(e),e.transport=null),n(e).triggerHandler(r.onDisconnect),delete e.messageId,delete e.groups,delete e.id,delete e._deferral}finally{u(e,e.state,i.connectionState.disconnected)}return e}},log:function(n){l(n,this.logging)}},i.fn.init.prototype=i.fn,i.noConflict=function(){return n.connection===i&&(n.connection=o),i},n.connection&&(o=n.connection),n.connection=n.signalR=i})(window.jQuery,window),function(n,t){"use strict";function u(f){var e=f.keepAliveData,o,s;f.state===r.connectionState.connected&&(o=new Date,o.setTime(o-e.lastKeepAlive),s=o.getTime(),s>=e.timeout?(f.log("Keep alive timed out.  Notifying transport that connection has been lost."),f.transport.lostConnection(f)):s>=e.timeoutWarning?e.userNotified||(f.log("Keep alive has been missed, connection may be dead/slow."),n(f).triggerHandler(i.onConnectionSlow),e.userNotified=!0):e.userNotified=!1),e.monitoring&&t.setTimeout(function(){u(f)},e.checkInterval)}var r=n.signalR,i=n.signalR.events,f=n.signalR.changeState;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 s=i==="webSockets"?"":n.baseUrl,f=s+n.appRelativeUrl,e="transport="+i+"&connectionId="+t.escape(n.id),o=this.getGroups(n);return n.data&&(e+="&connectionData="+t.escape(n.data)),r?(u&&(f=f+"/reconnect"),n.messageId&&(e+="&messageId="+t.escape(n.messageId)),o.length!==0&&(e+="&groups="+t.escape(JSON.stringify(o)))):f=f+"/connect",f+="?"+e,f=this.addQs(f,n),f+="&tid="+Math.floor(Math.random()*11)},maximizePersistentResponse:function(n){return{MessageId:n.C,Messages:n.M,Disconnect:typeof n.D!="undefined"?!0:!1,TimedOut:typeof n.T!="undefined"?!0:!1,LongPollDelay:n.L,ResetGroups:n.R,AddedGroups:n.G,RemovedGroups:n.g}},updateGroups:function(t,i,r,u){function f(i){n.each(i,function(n,i){t.groups["#"+i]=!0})}i?(t.groups={},f(i)):(r&&f(r),u&&n.each(u,function(n,i){delete t.groups["# "+i]}))},getGroups:function(t){var i=[];return t.groups&&n.each(t.groups,function(n){i.push(n.substr(1))}),i},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:r.ajaxDataType==="jsonp"?"GET":"POST",dataType:r.ajaxDataType,data:{data:u},success:function(t){t&&n(r).triggerHandler(i.onReceived,[t])},error:function(t,u){u!=="abort"&&(u!=="parsererror"||r.ajaxDataType!=="jsonp")&&n(r).triggerHandler(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,f;if(t.transport){if(f=n(t),t.transport.supportsKeepAlive&&t.keepAliveData.activated&&this.updateKeepAlive(t),!r)return;if(u=this.maximizePersistentResponse(r),u.Disconnect){t.log("Disconnect command received from server"),t.stop(!1,!1);return}this.updateGroups(t,u.ResetGroups,u.AddedGroups,u.RemovedGroups),u.Messages&&n.each(u.Messages,function(){try{f.triggerHandler(i.onReceived,[this])}catch(r){t.log("Error raising received "+r),n(t).triggerHandler(i.onError,[r])}}),u.MessageId&&(t.messageId=u.MessageId)}},monitorKeepAlive:function(t){var r=t.keepAliveData,f=this;r.monitoring?t.log("Tried to monitor keep alive but it's already being monitored"):(r.monitoring=!0,f.updateKeepAlive(t),t.keepAliveData.reconnectKeepAliveUpdate=function(){f.updateKeepAlive(t)},n(t).bind(i.onReconnect,t.keepAliveData.reconnectKeepAliveUpdate),t.log("Now monitoring keep alive with a warning timeout of "+r.timeoutWarning+" and a connection lost timeout of "+r.timeout),u(t))},stopMonitoringKeepAlive:function(t){var r=t.keepAliveData;r.monitoring&&(r.monitoring=!1,n(t).unbind(i.onReconnect,t.keepAliveData.reconnectKeepAliveUpdate),r={},t.log("Stopping the monitoring of the keep alive"))},updateKeepAlive:function(n){n.keepAliveData.lastKeepAlive=new Date},ensureReconnectingState:function(t){return f(t,r.connectionState.connected,r.connectionState.reconnecting)===!0&&n(t).triggerHandler(i.onReconnecting),t.state===r.connectionState.reconnecting},foreverFrame:{count:0,connections:{}}}}(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.webSockets={name:"webSockets",supportsKeepAlive:!0,attemptingReconnect:!1,currentSocketID:0,send:function(n,t){n.socket.send(t)},start:function(e,o,s){var c,a=!1,h=this,l=!o,v=n(e);if(t.MozWebSocket&&(t.WebSocket=t.MozWebSocket),!t.WebSocket){s();return}e.socket||(c=e.webSocketServerUrl?e.webSocketServerUrl:e.wsProtocol+e.host,c+=r.getUrl(e,this.name,l),e.log("Connecting to websocket endpoint '"+c+"'"),e.socket=new t.WebSocket(c),e.socket.ID=++h.currentSocketID,e.socket.onopen=function(){a=!0,e.log("Websocket opened"),h.attemptingReconnect&&(h.attemptingReconnect=!1),o?o():f(e,i.connectionState.reconnecting,i.connectionState.connected)===!0&&v.triggerHandler(u.onReconnect)},e.socket.onclose=function(t){if(this.ID===h.currentSocketID){if(a)typeof t.wasClean!="undefined"&&t.wasClean===!1?(n(e).triggerHandler(u.onError,[t.reason]),e.log("Unclean disconnect from websocket."+t.reason)):e.log("Websocket closed");else{s?s():l&&h.reconnect(e);return}h.reconnect(e)}},e.socket.onmessage=function(i){var f=t.JSON.parse(i.data),o=n(e);f&&(n.isEmptyObject(f)||f.M?r.processMessages(e,f):o.triggerHandler(u.onReceived,[f]))})},reconnect:function(n){var u=this;n.state!==i.connectionState.disconnected&&(u.attemptingReconnect||(u.attemptingReconnect=!0),t.setTimeout(function(){u.attemptingReconnect&&u.stop(n),r.ensureReconnectingState(n)&&(n.log("Websocket reconnecting"),u.start(n))},n.reconnectDelay))},lostConnection:function(n){this.reconnect(n)},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 r=n.signalR,u=n.signalR.events,f=n.signalR.changeState,i=r.transports._logic;r.transports.serverSentEvents={name:"serverSentEvents",supportsKeepAlive:!0,reconnectTimeout:!1,currentEventSourceID:0,timeOut:3e3,start:function(e,o,s){var h=this,l=!1,y=n(e),c=!o,v,a;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}v=i.getUrl(e,this.name,c);try{e.log("Attempting to connect to SSE endpoint '"+v+"'"),e.eventSource=new t.EventSource(v),e.eventSource.ID=++h.currentEventSourceID}catch(p){e.log("EventSource failed trying to connect with error "+p.Message),s?s():(y.triggerHandler(u.onError,[p]),c&&h.reconnect(e));return}a=t.setTimeout(function(){l===!1&&(e.log("EventSource timed out trying to connect"),e.log("EventSource readyState: "+e.eventSource.readyState),c||h.stop(e),c?e.eventSource.readyState!==t.EventSource.CONNECTING&&e.eventSource.readyState!==t.EventSource.OPEN&&h.reconnect(e):s&&s())},h.timeOut),e.eventSource.addEventListener("open",function(){e.log("EventSource connected"),a&&t.clearTimeout(a),h.reconnectTimeout&&t.clearTimeout(h.reconnectTimeout),l===!1&&(l=!0,o?o():f(e,r.connectionState.reconnecting,r.connectionState.connected)===!0&&y.triggerHandler(u.onReconnect))},!1),e.eventSource.addEventListener("message",function(n){n.data!=="initialized"&&i.processMessages(e,t.JSON.parse(n.data))},!1),e.eventSource.addEventListener("error",function(n){if(this.ID===h.currentEventSourceID){if(!l){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"),h.reconnect(e)):(e.log("EventSource error"),y.triggerHandler(u.onError))}},!1)},reconnect:function(n){var r=this;r.reconnectTimeout=t.setTimeout(function(){r.stop(n),i.ensureReconnectingState(n)&&(n.log("EventSource reconnecting"),r.start(n))},n.reconnectDelay)},lostConnection:function(n){this.reconnect(n)},send:function(n,t){i.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){i.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",supportsKeepAlive:!0,timeOut:3e3,start:function(r,u,f){var o=this,s=i.foreverFrame.count+=1,h,e=n("<iframe data-signalr-connection-id='"+r.id+"' style='position:absolute;top:0;left:0;width:0;height:0;visibility:hidden;' src=''></iframe>");if(t.EventSource){f&&(r.log("This browser supports SSE, skipping Forever Frame."),f());return}h=i.getUrl(r,this.name),h+="&frameId="+s,n("body").append(e),e.prop("src",h),i.foreverFrame.connections[s]=r,r.log("Binding to iframe's readystatechange event."),e.bind("readystatechange",function(){n.inArray(this.readyState,["loaded","complete"])>=0&&(r.log("Forever frame iframe readyState changed to "+this.readyState+", reconnecting"),o.reconnect(r))}),r.frame=e[0],r.frameId=s,u&&(r.onSuccess=u),t.setTimeout(function(){r.onSuccess&&(r.log("Failed to connect using forever frame source, it timed out after "+o.timeOut+"ms."),o.stop(r),f&&f())},o.timeOut)},reconnect:function(n){var r=this;t.setTimeout(function(){if(n.frame&&i.ensureReconnectingState(n)){var u=n.frame,t=i.getUrl(n,r.name,!0)+"&frameId="+n.frameId;n.log("Updating iframe src to '"+t+"'."),u.src=t}},n.reconnectDelay)},lostConnection:function(n){this.reconnect(n)},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;if(t.frame){if(t.frame.stop)t.frame.stop();else try{r=t.frame.contentWindow||t.frame.contentDocument,r.document&&r.document.execCommand&&r.document.execCommand("Stop")}catch(u){t.log("SignalR: Error occured when stopping foreverFrame transport. Message = "+u.message)}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).triggerHandler(u.onReconnect)}}}(window.jQuery,window),function(n,t){"use strict";var r=n.signalR,f=n.signalR.events,e=n.signalR.changeState,u=n.signalR.isDisconnecting,i=r.transports._logic;r.transports.longPolling={name:"longPolling",supportsKeepAlive:!1,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){var d=a.messageId,g=d===null,k=!g,b=i.getUrl(a,l.name,k,v),y=null,p=!1,w=function(){p===!1&&(o.log("Raising the reconnect event"),e(o,r.connectionState.reconnecting,r.connectionState.connected)===!0&&(n(a).triggerHandler(f.onReconnect),p=!0))};(k!==!0||v!==!0||i.ensureReconnectingState(o))&&(o.log("Attempting to connect to '"+b+"' using longPolling."),a.pollXhr=n.ajax({url:b,global:!1,cache:!1,type:"GET",dataType:o.ajaxDataType,success:function(r){var e=0,o=!1,f;(r&&(f=i.maximizePersistentResponse(r)),c===!1&&(s(),c=!0),v===!0&&w(),i.processMessages(a,r),f&&n.type(f.LongPollDelay)==="number"&&(e=f.LongPollDelay),f&&f.TimedOut&&(o=f.TimedOut),f&&f.Disconnect)||u(a)!==!0&&(e>0?t.setTimeout(function(){h(a,o)},e):h(a,o))},error:function(i,e){if(e==="abort"){o.log("Aborted xhr requst.");return}o.state!==r.connectionState.reconnecting&&(o.log("An error occurred using longPolling. Status = "+e+". "+i.responseText),n(a).triggerHandler(f.onError,[i.responseText])),t.clearTimeout(y),t.setTimeout(function(){u(a)===!1&&h(a,!0)},o.reconnectDelay)}}),v===!0&&(y=t.setTimeout(w,l.reconnectDelay)))})(o),t.setTimeout(function(){c===!1&&(s(),c=!0)},150)},250)},lostConnection:function(){throw new Error("Lost Connection not handled for LongPolling");},send:function(n,t){i.ajaxSend(n,t)},stop:function(n){n.pollXhr&&(n.pollXhr.abort(),n.pollXhr=null,delete n.pollXhr)},abort:function(n,t){i.ajaxAbort(n,t)}}}(window.jQuery,window),function(n,t){"use strict";function f(n){return n+s}function h(t){return n.isFunction(t)?null:n.type(t)==="undefined"?null:t}function o(n){for(var t in n)if(n.hasOwnProperty(t))return!0;return!1}function r(n,t){return new r.fn.init(n,t)}function i(t,r){var u={qs:null,logging:!1,useDefaultPath:!0};return n.extend(u,r),(!t||u.useDefaultPath)&&(t=(t||"")+"/signalr"),new i.fn.init(t,u)}var e=0,u={},s=".hubProxy";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,this._={callbackMap:{}}},hasSubscriptions:function(){return o(this._.callbackMap)},on:function(t,i){var u=this,r=u._.callbackMap;return t=t.toLowerCase(),r[t]||(r[t]={}),r[t][i]=function(n,t){i.apply(u,t)},n(u).bind(f(t),r[t][i]),u},off:function(t,i){var u=this,e=u._.callbackMap,r;return t=t.toLowerCase(),r=e[t],r&&(r[i]?(n(u).unbind(f(t),r[i]),delete r[i],o(r)||delete e[t]):i||(n(u).unbind(f(t)),delete e[t])),u},invoke:function(i){var r=this,c=n.makeArray(arguments).slice(1),l=c.map(h),o={H:r.hubName,M:i,A:l,I:e},f=n.Deferred(),s=function(t){var i=r._maximizeHubResponse(t);n.extend(r.state,i.State),i.Error?(i.StackTrace&&r.connection.log(i.Error+"\n"+i.StackTrace),f.rejectWith(r,[i.Error])):f.resolveWith(r,[i.Result])};return u[e.toString()]={scope:r,method:s},e+=1,n.isEmptyObject(r.state)||(o.S=r.state),r.connection.send(t.JSON.stringify(o)),f.promise()},_maximizeHubResponse:function(n){return{State:n.S,Result:n.R,Id:n.I,Error:n.E,StackTrace:n.T}}},r.fn.init.prototype=r.fn,i.fn=i.prototype=n.connection(),i.fn.init=function(t,i){var e={qs:null,logging:!1,useDefaultPath:!0},r=this;n.extend(e,i),n.signalR.fn.init.call(r,t,e.qs,e.logging),r.proxies={},r.received(function(t){var i,s,o,e,c,h;t&&(typeof t.I!="undefined"?(o=t.I.toString(),e=u[o],e&&(u[o]=null,delete u[o],e.method.call(e.scope,t))):(i=this._maximizeClientHubInvocation(t),r.log("Triggering client hub event '"+i.Method+"' on hub '"+i.Hub+"'."),c=i.Hub.toLowerCase(),h=i.Method.toLowerCase(),s=this.proxies[c],n.extend(s.state,i.State),n(s).triggerHandler(f(h),[i.Args])))})},i.fn._maximizeClientHubInvocation=function(n){return{Hub:n.H,Method:n.M,Args:n.A,State:n.S}},i.fn._registerSubscribedHubs=function(){this._subscribedToHubs||(this._subscribedToHubs=!0,this.starting(function(){var i=[];n.each(this.proxies,function(n){this.hasSubscriptions()&&i.push({name:n})}),this.data=t.JSON.stringify(i)}))},i.fn.createHubProxy=function(n){n=n.toLowerCase();var t=this.proxies[n];return t||(t=r(this,n),this.proxies[n]=t),this._registerSubscribedHubs(),t},i.fn.init.prototype=i.fn,n.hubConnection=i}(window.jQuery,window),function(n){n.signalR.version="1.0.0.rc1"}(window.jQuery)

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
KPMG
United States United States
My passion is to learn, analyze, design (OOAD), architect, code and work with all team members to create competitive products in the market using efficient ways.

Interested area are .NET, MVC, client-side development, OData, SQL Server BI Solutions( SSAS & SSRS) ,PHP, MySQL, Visual Studio Automation&Performance Testing, Agile development and architect Frameworks and application integration solutions

Comments and Discussions