Best JavaScript code snippet using cypress
jquery.signalR-2.2.2.js
Source:jquery.signalR-2.2.2.js
...838 // Check if the keep alive has completely timed out839 if (timeElapsed >= keepAliveData.timeout) {840 connection.log("Keep alive timed out. Notifying transport that connection has been lost.");841 // Notify transport that the connection has been lost842 connection.transport.lostConnection(connection);843 } else if (timeElapsed >= keepAliveData.timeoutWarning) {844 // This is to assure that the user only gets a single warning845 if (!keepAliveData.userNotified) {846 connection.log("Keep alive has been missed, connection may be dead/slow.");847 $(connection).triggerHandler(events.onConnectionSlow);848 keepAliveData.userNotified = true;849 }850 } else {851 keepAliveData.userNotified = false;852 }853 }854 }855 function getAjaxUrl(connection, path) {856 var url = connection.url + path;857 if (connection.transport) {858 url += "?transport=" + connection.transport.name;859 }860 return transportLogic.prepareQueryString(connection, url);861 }862 function InitHandler(connection) {863 this.connection = connection;864 this.startRequested = false;865 this.startCompleted = false;866 this.connectionStopped = false;867 }868 InitHandler.prototype = {869 start: function (transport, onSuccess, onFallback) {870 var that = this,871 connection = that.connection,872 failCalled = false;873 if (that.startRequested || that.connectionStopped) {874 connection.log("WARNING! " + transport.name + " transport cannot be started. Initialization ongoing or completed.");875 return;876 }877 connection.log(transport.name + " transport starting.");878 transport.start(connection, function () {879 if (!failCalled) {880 that.initReceived(transport, onSuccess);881 }882 }, function (error) {883 // Don't allow the same transport to cause onFallback to be called twice884 if (!failCalled) {885 failCalled = true;886 that.transportFailed(transport, error, onFallback);887 }888 // Returns true if the transport should stop;889 // false if it should attempt to reconnect890 return !that.startCompleted || that.connectionStopped;891 });892 that.transportTimeoutHandle = window.setTimeout(function () {893 if (!failCalled) {894 failCalled = true;895 connection.log(transport.name + " transport timed out when trying to connect.");896 that.transportFailed(transport, undefined, onFallback);897 }898 }, connection._.totalTransportConnectTimeout);899 },900 stop: function () {901 this.connectionStopped = true;902 window.clearTimeout(this.transportTimeoutHandle);903 signalR.transports._logic.tryAbortStartRequest(this.connection);904 },905 initReceived: function (transport, onSuccess) {906 var that = this,907 connection = that.connection;908 if (that.startRequested) {909 connection.log("WARNING! The client received multiple init messages.");910 return;911 }912 if (that.connectionStopped) {913 return;914 }915 that.startRequested = true;916 window.clearTimeout(that.transportTimeoutHandle);917 connection.log(transport.name + " transport connected. Initiating start request.");918 signalR.transports._logic.ajaxStart(connection, function () {919 that.startCompleted = true;920 onSuccess();921 });922 },923 transportFailed: function (transport, error, onFallback) {924 var connection = this.connection,925 deferred = connection._deferral,926 wrappedError;927 if (this.connectionStopped) {928 return;929 }930 window.clearTimeout(this.transportTimeoutHandle);931 if (!this.startRequested) {932 transport.stop(connection);933 connection.log(transport.name + " transport failed to connect. Attempting to fall back.");934 onFallback();935 } else if (!this.startCompleted) {936 // Do not attempt to fall back if a start request is ongoing during a transport failure.937 // Instead, trigger an error and stop the connection.938 wrappedError = signalR._.error(signalR.resources.errorDuringStartRequest, error);939 connection.log(transport.name + " transport failed during the start request. Stopping the connection.");940 $(connection).triggerHandler(events.onError, [wrappedError]);941 if (deferred) {942 deferred.reject(wrappedError);943 }944 connection.stop();945 } else {946 // The start request has completed, but the connection has not stopped.947 // No need to do anything here. The transport should attempt its normal reconnect logic.948 }949 }950 };951 transportLogic = signalR.transports._logic = {952 ajax: function (connection, options) {953 return $.ajax(954 $.extend(/*deep copy*/ true, {}, $.signalR.ajaxDefaults, {955 type: "GET",956 data: {},957 xhrFields: { withCredentials: connection.withCredentials },958 contentType: connection.contentType,959 dataType: connection.ajaxDataType960 }, options));961 },962 pingServer: function (connection) {963 /// <summary>Pings the server</summary>964 /// <param name="connection" type="signalr">Connection associated with the server ping</param>965 /// <returns type="signalR" />966 var url,967 xhr,968 deferral = $.Deferred();969 if (connection.transport) {970 url = connection.url + "/ping";971 url = transportLogic.addQs(url, connection.qs);972 xhr = transportLogic.ajax(connection, {973 url: url,974 success: function (result) {975 var data;976 try {977 data = connection._parseResponse(result);978 }979 catch (error) {980 deferral.reject(981 signalR._.transportError(982 signalR.resources.pingServerFailedParse,983 connection.transport,984 error,985 xhr986 )987 );988 connection.stop();989 return;990 }991 if (data.Response === "pong") {992 deferral.resolve();993 }994 else {995 deferral.reject(996 signalR._.transportError(997 signalR._.format(signalR.resources.pingServerFailedInvalidResponse, result),998 connection.transport,999 null /* error */,1000 xhr1001 )1002 );1003 }1004 },1005 error: function (error) {1006 if (error.status === 401 || error.status === 403) {1007 deferral.reject(1008 signalR._.transportError(1009 signalR._.format(signalR.resources.pingServerFailedStatusCode, error.status),1010 connection.transport,1011 error,1012 xhr1013 )1014 );1015 connection.stop();1016 }1017 else {1018 deferral.reject(1019 signalR._.transportError(1020 signalR.resources.pingServerFailed,1021 connection.transport,1022 error,1023 xhr1024 )1025 );1026 }1027 }1028 });1029 }1030 else {1031 deferral.reject(1032 signalR._.transportError(1033 signalR.resources.noConnectionTransport,1034 connection.transport1035 )1036 );1037 }1038 return deferral.promise();1039 },1040 prepareQueryString: function (connection, url) {1041 var preparedUrl;1042 // Use addQs to start since it handles the ?/& prefix for us1043 preparedUrl = transportLogic.addQs(url, "clientProtocol=" + connection.clientProtocol);1044 // Add the user-specified query string params if any1045 preparedUrl = transportLogic.addQs(preparedUrl, connection.qs);1046 if (connection.token) {1047 preparedUrl += "&connectionToken=" + window.encodeURIComponent(connection.token);1048 }1049 if (connection.data) {1050 preparedUrl += "&connectionData=" + window.encodeURIComponent(connection.data);1051 }1052 return preparedUrl;1053 },1054 addQs: function (url, qs) {1055 var appender = url.indexOf("?") !== -1 ? "&" : "?",1056 firstChar;1057 if (!qs) {1058 return url;1059 }1060 if (typeof (qs) === "object") {1061 return url + appender + $.param(qs);1062 }1063 if (typeof (qs) === "string") {1064 firstChar = qs.charAt(0);1065 if (firstChar === "?" || firstChar === "&") {1066 appender = "";1067 }1068 return url + appender + qs;1069 }1070 throw new Error("Query string property must be either a string or object.");1071 },1072 // BUG #2953: The url needs to be same otherwise it will cause a memory leak1073 getUrl: function (connection, transport, reconnecting, poll, ajaxPost) {1074 /// <summary>Gets the url for making a GET based connect request</summary>1075 var baseUrl = transport === "webSockets" ? "" : connection.baseUrl,1076 url = baseUrl + connection.appRelativeUrl,1077 qs = "transport=" + transport;1078 if (!ajaxPost && connection.groupsToken) {1079 qs += "&groupsToken=" + window.encodeURIComponent(connection.groupsToken);1080 }1081 if (!reconnecting) {1082 url += "/connect";1083 } else {1084 if (poll) {1085 // longPolling transport specific1086 url += "/poll";1087 } else {1088 url += "/reconnect";1089 }1090 if (!ajaxPost && connection.messageId) {1091 qs += "&messageId=" + window.encodeURIComponent(connection.messageId);1092 }1093 }1094 url += "?" + qs;1095 url = transportLogic.prepareQueryString(connection, url);1096 if (!ajaxPost) {1097 url += "&tid=" + Math.floor(Math.random() * 11);1098 }1099 return url;1100 },1101 maximizePersistentResponse: function (minPersistentResponse) {1102 return {1103 MessageId: minPersistentResponse.C,1104 Messages: minPersistentResponse.M,1105 Initialized: typeof (minPersistentResponse.S) !== "undefined" ? true : false,1106 ShouldReconnect: typeof (minPersistentResponse.T) !== "undefined" ? true : false,1107 LongPollDelay: minPersistentResponse.L,1108 GroupsToken: minPersistentResponse.G1109 };1110 },1111 updateGroups: function (connection, groupsToken) {1112 if (groupsToken) {1113 connection.groupsToken = groupsToken;1114 }1115 },1116 stringifySend: function (connection, message) {1117 if (typeof (message) === "string" || typeof (message) === "undefined" || message === null) {1118 return message;1119 }1120 return connection.json.stringify(message);1121 },1122 ajaxSend: function (connection, data) {1123 var payload = transportLogic.stringifySend(connection, data),1124 url = getAjaxUrl(connection, "/send"),1125 xhr,1126 onFail = function (error, connection) {1127 $(connection).triggerHandler(events.onError, [signalR._.transportError(signalR.resources.sendFailed, connection.transport, error, xhr), data]);1128 };1129 xhr = transportLogic.ajax(connection, {1130 url: url,1131 type: connection.ajaxDataType === "jsonp" ? "GET" : "POST",1132 contentType: signalR._.defaultContentType,1133 data: {1134 data: payload1135 },1136 success: function (result) {1137 var res;1138 if (result) {1139 try {1140 res = connection._parseResponse(result);1141 }1142 catch (error) {1143 onFail(error, connection);1144 connection.stop();1145 return;1146 }1147 transportLogic.triggerReceived(connection, res);1148 }1149 },1150 error: function (error, textStatus) {1151 if (textStatus === "abort" || textStatus === "parsererror") {1152 // The parsererror happens for sends that don't return any data, and hence1153 // don't write the jsonp callback to the response. This is harder to fix on the server1154 // so just hack around it on the client for now.1155 return;1156 }1157 onFail(error, connection);1158 }1159 });1160 return xhr;1161 },1162 ajaxAbort: function (connection, async) {1163 if (typeof (connection.transport) === "undefined") {1164 return;1165 }1166 // Async by default unless explicitly overidden1167 async = typeof async === "undefined" ? true : async;1168 var url = getAjaxUrl(connection, "/abort");1169 transportLogic.ajax(connection, {1170 url: url,1171 async: async,1172 timeout: 1000,1173 type: "POST"1174 });1175 connection.log("Fired ajax abort async = " + async + ".");1176 },1177 ajaxStart: function (connection, onSuccess) {1178 var rejectDeferred = function (error) {1179 var deferred = connection._deferral;1180 if (deferred) {1181 deferred.reject(error);1182 }1183 },1184 triggerStartError = function (error) {1185 connection.log("The start request failed. Stopping the connection.");1186 $(connection).triggerHandler(events.onError, [error]);1187 rejectDeferred(error);1188 connection.stop();1189 };1190 connection._.startRequest = transportLogic.ajax(connection, {1191 url: getAjaxUrl(connection, "/start"),1192 success: function (result, statusText, xhr) {1193 var data;1194 try {1195 data = connection._parseResponse(result);1196 } catch (error) {1197 triggerStartError(signalR._.error(1198 signalR._.format(signalR.resources.errorParsingStartResponse, result),1199 error, xhr));1200 return;1201 }1202 if (data.Response === "started") {1203 onSuccess();1204 } else {1205 triggerStartError(signalR._.error(1206 signalR._.format(signalR.resources.invalidStartResponse, result),1207 null /* error */, xhr));1208 }1209 },1210 error: function (xhr, statusText, error) {1211 if (statusText !== startAbortText) {1212 triggerStartError(signalR._.error(1213 signalR.resources.errorDuringStartRequest,1214 error, xhr));1215 } else {1216 // Stop has been called, no need to trigger the error handler1217 // or stop the connection again with onStartError1218 connection.log("The start request aborted because connection.stop() was called.");1219 rejectDeferred(signalR._.error(1220 signalR.resources.stoppedDuringStartRequest,1221 null /* error */, xhr));1222 }1223 }1224 });1225 },1226 tryAbortStartRequest: function (connection) {1227 if (connection._.startRequest) {1228 // If the start request has already completed this will noop.1229 connection._.startRequest.abort(startAbortText);1230 delete connection._.startRequest;1231 }1232 },1233 tryInitialize: function (connection, persistentResponse, onInitialized) {1234 if (persistentResponse.Initialized && onInitialized) {1235 onInitialized();1236 } else if (persistentResponse.Initialized) {1237 connection.log("WARNING! The client received an init message after reconnecting.");1238 }1239 },1240 triggerReceived: function (connection, data) {1241 if (!connection._.connectingMessageBuffer.tryBuffer(data)) {1242 $(connection).triggerHandler(events.onReceived, [data]);1243 }1244 },1245 processMessages: function (connection, minData, onInitialized) {1246 var data;1247 // Update the last message time stamp1248 transportLogic.markLastMessage(connection);1249 if (minData) {1250 data = transportLogic.maximizePersistentResponse(minData);1251 transportLogic.updateGroups(connection, data.GroupsToken);1252 if (data.MessageId) {1253 connection.messageId = data.MessageId;1254 }1255 if (data.Messages) {1256 $.each(data.Messages, function (index, message) {1257 transportLogic.triggerReceived(connection, message);1258 });1259 transportLogic.tryInitialize(connection, data, onInitialized);1260 }1261 }1262 },1263 monitorKeepAlive: function (connection) {1264 var keepAliveData = connection._.keepAliveData;1265 // If we haven't initiated the keep alive timeouts then we need to1266 if (!keepAliveData.monitoring) {1267 keepAliveData.monitoring = true;1268 transportLogic.markLastMessage(connection);1269 // Save the function so we can unbind it on stop1270 connection._.keepAliveData.reconnectKeepAliveUpdate = function () {1271 // Mark a new message so that keep alive doesn't time out connections1272 transportLogic.markLastMessage(connection);1273 };1274 // Update Keep alive on reconnect1275 $(connection).bind(events.onReconnect, connection._.keepAliveData.reconnectKeepAliveUpdate);1276 connection.log("Now monitoring keep alive with a warning timeout of " + keepAliveData.timeoutWarning + ", keep alive timeout of " + keepAliveData.timeout + " and disconnecting timeout of " + connection.disconnectTimeout);1277 } else {1278 connection.log("Tried to monitor keep alive but it's already being monitored.");1279 }1280 },1281 stopMonitoringKeepAlive: function (connection) {1282 var keepAliveData = connection._.keepAliveData;1283 // Only attempt to stop the keep alive monitoring if its being monitored1284 if (keepAliveData.monitoring) {1285 // Stop monitoring1286 keepAliveData.monitoring = false;1287 // Remove the updateKeepAlive function from the reconnect event1288 $(connection).unbind(events.onReconnect, connection._.keepAliveData.reconnectKeepAliveUpdate);1289 // Clear all the keep alive data1290 connection._.keepAliveData = {};1291 connection.log("Stopping the monitoring of the keep alive.");1292 }1293 },1294 startHeartbeat: function (connection) {1295 connection._.lastActiveAt = new Date().getTime();1296 beat(connection);1297 },1298 markLastMessage: function (connection) {1299 connection._.lastMessageAt = new Date().getTime();1300 },1301 markActive: function (connection) {1302 if (transportLogic.verifyLastActive(connection)) {1303 connection._.lastActiveAt = new Date().getTime();1304 return true;1305 }1306 return false;1307 },1308 isConnectedOrReconnecting: function (connection) {1309 return connection.state === signalR.connectionState.connected ||1310 connection.state === signalR.connectionState.reconnecting;1311 },1312 ensureReconnectingState: function (connection) {1313 if (changeState(connection,1314 signalR.connectionState.connected,1315 signalR.connectionState.reconnecting) === true) {1316 $(connection).triggerHandler(events.onReconnecting);1317 }1318 return connection.state === signalR.connectionState.reconnecting;1319 },1320 clearReconnectTimeout: function (connection) {1321 if (connection && connection._.reconnectTimeout) {1322 window.clearTimeout(connection._.reconnectTimeout);1323 delete connection._.reconnectTimeout;1324 }1325 },1326 verifyLastActive: function (connection) {1327 if (new Date().getTime() - connection._.lastActiveAt >= connection.reconnectWindow) {1328 var message = signalR._.format(signalR.resources.reconnectWindowTimeout, new Date(connection._.lastActiveAt), connection.reconnectWindow);1329 connection.log(message);1330 $(connection).triggerHandler(events.onError, [signalR._.error(message, /* source */ "TimeoutException")]);1331 connection.stop(/* async */ false, /* notifyServer */ false);1332 return false;1333 }1334 return true;1335 },1336 reconnect: function (connection, transportName) {1337 var transport = signalR.transports[transportName];1338 // We should only set a reconnectTimeout if we are currently connected1339 // and a reconnectTimeout isn't already set.1340 if (transportLogic.isConnectedOrReconnecting(connection) && !connection._.reconnectTimeout) {1341 // Need to verify before the setTimeout occurs because an application sleep could occur during the setTimeout duration.1342 if (!transportLogic.verifyLastActive(connection)) {1343 return;1344 }1345 connection._.reconnectTimeout = window.setTimeout(function () {1346 if (!transportLogic.verifyLastActive(connection)) {1347 return;1348 }1349 transport.stop(connection);1350 if (transportLogic.ensureReconnectingState(connection)) {1351 connection.log(transportName + " reconnecting.");1352 transport.start(connection);1353 }1354 }, connection.reconnectDelay);1355 }1356 },1357 handleParseFailure: function (connection, result, error, onFailed, context) {1358 var wrappedError = signalR._.transportError(1359 signalR._.format(signalR.resources.parseFailed, result),1360 connection.transport,1361 error,1362 context);1363 // If we're in the initialization phase trigger onFailed, otherwise stop the connection.1364 if (onFailed && onFailed(wrappedError)) {1365 connection.log("Failed to parse server response while attempting to connect.");1366 } else {1367 $(connection).triggerHandler(events.onError, [wrappedError]);1368 connection.stop();1369 }1370 },1371 initHandler: function (connection) {1372 return new InitHandler(connection);1373 },1374 foreverFrame: {1375 count: 0,1376 connections: {}1377 }1378 };1379}(window.jQuery, window));1380/* jquery.signalR.transports.webSockets.js */1381// Copyright (c) .NET Foundation. All rights reserved.1382// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.1383/*global window:false */1384/// <reference path="jquery.signalR.transports.common.js" />1385(function ($, window, undefined) {1386 var signalR = $.signalR,1387 events = $.signalR.events,1388 changeState = $.signalR.changeState,1389 transportLogic = signalR.transports._logic;1390 signalR.transports.webSockets = {1391 name: "webSockets",1392 supportsKeepAlive: function () {1393 return true;1394 },1395 send: function (connection, data) {1396 var payload = transportLogic.stringifySend(connection, data);1397 try {1398 connection.socket.send(payload);1399 } catch (ex) {1400 $(connection).triggerHandler(events.onError,1401 [signalR._.transportError(1402 signalR.resources.webSocketsInvalidState,1403 connection.transport,1404 ex,1405 connection.socket1406 ),1407 data]);1408 }1409 },1410 start: function (connection, onSuccess, onFailed) {1411 var url,1412 opened = false,1413 that = this,1414 reconnecting = !onSuccess,1415 $connection = $(connection);1416 if (!window.WebSocket) {1417 onFailed();1418 return;1419 }1420 if (!connection.socket) {1421 if (connection.webSocketServerUrl) {1422 url = connection.webSocketServerUrl;1423 } else {1424 url = connection.wsProtocol + connection.host;1425 }1426 url += transportLogic.getUrl(connection, this.name, reconnecting);1427 connection.log("Connecting to websocket endpoint '" + url + "'.");1428 connection.socket = new window.WebSocket(url);1429 connection.socket.onopen = function () {1430 opened = true;1431 connection.log("Websocket opened.");1432 transportLogic.clearReconnectTimeout(connection);1433 if (changeState(connection,1434 signalR.connectionState.reconnecting,1435 signalR.connectionState.connected) === true) {1436 $connection.triggerHandler(events.onReconnect);1437 }1438 };1439 connection.socket.onclose = function (event) {1440 var error;1441 // Only handle a socket close if the close is from the current socket.1442 // Sometimes on disconnect the server will push down an onclose event1443 // to an expired socket.1444 if (this === connection.socket) {1445 if (opened && typeof event.wasClean !== "undefined" && event.wasClean === false) {1446 // Ideally this would use the websocket.onerror handler (rather than checking wasClean in onclose) but1447 // I found in some circumstances Chrome won't call onerror. This implementation seems to work on all browsers.1448 error = signalR._.transportError(1449 signalR.resources.webSocketClosed,1450 connection.transport,1451 event);1452 connection.log("Unclean disconnect from websocket: " + (event.reason || "[no reason given]."));1453 } else {1454 connection.log("Websocket closed.");1455 }1456 if (!onFailed || !onFailed(error)) {1457 if (error) {1458 $(connection).triggerHandler(events.onError, [error]);1459 }1460 that.reconnect(connection);1461 }1462 }1463 };1464 connection.socket.onmessage = function (event) {1465 var data;1466 try {1467 data = connection._parseResponse(event.data);1468 }1469 catch (error) {1470 transportLogic.handleParseFailure(connection, event.data, error, onFailed, event);1471 return;1472 }1473 if (data) {1474 // data.M is PersistentResponse.Messages1475 if ($.isEmptyObject(data) || data.M) {1476 transportLogic.processMessages(connection, data, onSuccess);1477 } else {1478 // For websockets we need to trigger onReceived1479 // for callbacks to outgoing hub calls.1480 transportLogic.triggerReceived(connection, data);1481 }1482 }1483 };1484 }1485 },1486 reconnect: function (connection) {1487 transportLogic.reconnect(connection, this.name);1488 },1489 lostConnection: function (connection) {1490 this.reconnect(connection);1491 },1492 stop: function (connection) {1493 // Don't trigger a reconnect after stopping1494 transportLogic.clearReconnectTimeout(connection);1495 if (connection.socket) {1496 connection.log("Closing the Websocket.");1497 connection.socket.close();1498 connection.socket = null;1499 }1500 },1501 abort: function (connection, async) {1502 transportLogic.ajaxAbort(connection, async);1503 }1504 };1505}(window.jQuery, window));1506/* jquery.signalR.transports.serverSentEvents.js */1507// Copyright (c) .NET Foundation. All rights reserved.1508// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.1509/*global window:false */1510/// <reference path="jquery.signalR.transports.common.js" />1511(function ($, window, undefined) {1512 var signalR = $.signalR,1513 events = $.signalR.events,1514 changeState = $.signalR.changeState,1515 transportLogic = signalR.transports._logic,1516 clearReconnectAttemptTimeout = function (connection) {1517 window.clearTimeout(connection._.reconnectAttemptTimeoutHandle);1518 delete connection._.reconnectAttemptTimeoutHandle;1519 };1520 signalR.transports.serverSentEvents = {1521 name: "serverSentEvents",1522 supportsKeepAlive: function () {1523 return true;1524 },1525 timeOut: 3000,1526 start: function (connection, onSuccess, onFailed) {1527 var that = this,1528 opened = false,1529 $connection = $(connection),1530 reconnecting = !onSuccess,1531 url;1532 if (connection.eventSource) {1533 connection.log("The connection already has an event source. Stopping it.");1534 connection.stop();1535 }1536 if (!window.EventSource) {1537 if (onFailed) {1538 connection.log("This browser doesn't support SSE.");1539 onFailed();1540 }1541 return;1542 }1543 url = transportLogic.getUrl(connection, this.name, reconnecting);1544 try {1545 connection.log("Attempting to connect to SSE endpoint '" + url + "'.");1546 connection.eventSource = new window.EventSource(url, { withCredentials: connection.withCredentials });1547 }1548 catch (e) {1549 connection.log("EventSource failed trying to connect with error " + e.Message + ".");1550 if (onFailed) {1551 // The connection failed, call the failed callback1552 onFailed();1553 } else {1554 $connection.triggerHandler(events.onError, [signalR._.transportError(signalR.resources.eventSourceFailedToConnect, connection.transport, e)]);1555 if (reconnecting) {1556 // If we were reconnecting, rather than doing initial connect, then try reconnect again1557 that.reconnect(connection);1558 }1559 }1560 return;1561 }1562 if (reconnecting) {1563 connection._.reconnectAttemptTimeoutHandle = window.setTimeout(function () {1564 if (opened === false) {1565 // If we're reconnecting and the event source is attempting to connect,1566 // don't keep retrying. This causes duplicate connections to spawn.1567 if (connection.eventSource.readyState !== window.EventSource.OPEN) {1568 // If we were reconnecting, rather than doing initial connect, then try reconnect again1569 that.reconnect(connection);1570 }1571 }1572 },1573 that.timeOut);1574 }1575 connection.eventSource.addEventListener("open", function (e) {1576 connection.log("EventSource connected.");1577 clearReconnectAttemptTimeout(connection);1578 transportLogic.clearReconnectTimeout(connection);1579 if (opened === false) {1580 opened = true;1581 if (changeState(connection,1582 signalR.connectionState.reconnecting,1583 signalR.connectionState.connected) === true) {1584 $connection.triggerHandler(events.onReconnect);1585 }1586 }1587 }, false);1588 connection.eventSource.addEventListener("message", function (e) {1589 var res;1590 // process messages1591 if (e.data === "initialized") {1592 return;1593 }1594 try {1595 res = connection._parseResponse(e.data);1596 }1597 catch (error) {1598 transportLogic.handleParseFailure(connection, e.data, error, onFailed, e);1599 return;1600 }1601 transportLogic.processMessages(connection, res, onSuccess);1602 }, false);1603 connection.eventSource.addEventListener("error", function (e) {1604 var error = signalR._.transportError(1605 signalR.resources.eventSourceError,1606 connection.transport,1607 e);1608 // Only handle an error if the error is from the current Event Source.1609 // Sometimes on disconnect the server will push down an error event1610 // to an expired Event Source.1611 if (this !== connection.eventSource) {1612 return;1613 }1614 if (onFailed && onFailed(error)) {1615 return;1616 }1617 connection.log("EventSource readyState: " + connection.eventSource.readyState + ".");1618 if (e.eventPhase === window.EventSource.CLOSED) {1619 // We don't use the EventSource's native reconnect function as it1620 // doesn't allow us to change the URL when reconnecting. We need1621 // to change the URL to not include the /connect suffix, and pass1622 // the last message id we received.1623 connection.log("EventSource reconnecting due to the server connection ending.");1624 that.reconnect(connection);1625 } else {1626 // connection error1627 connection.log("EventSource error.");1628 $connection.triggerHandler(events.onError, [error]);1629 }1630 }, false);1631 },1632 reconnect: function (connection) {1633 transportLogic.reconnect(connection, this.name);1634 },1635 lostConnection: function (connection) {1636 this.reconnect(connection);1637 },1638 send: function (connection, data) {1639 transportLogic.ajaxSend(connection, data);1640 },1641 stop: function (connection) {1642 // Don't trigger a reconnect after stopping1643 clearReconnectAttemptTimeout(connection);1644 transportLogic.clearReconnectTimeout(connection);1645 if (connection && connection.eventSource) {1646 connection.log("EventSource calling close().");1647 connection.eventSource.close();1648 connection.eventSource = null;1649 delete connection.eventSource;1650 }1651 },1652 abort: function (connection, async) {1653 transportLogic.ajaxAbort(connection, async);1654 }1655 };1656}(window.jQuery, window));1657/* jquery.signalR.transports.foreverFrame.js */1658// Copyright (c) .NET Foundation. All rights reserved.1659// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.1660/*global window:false */1661/// <reference path="jquery.signalR.transports.common.js" />1662(function ($, window, undefined) {1663 var signalR = $.signalR,1664 events = $.signalR.events,1665 changeState = $.signalR.changeState,1666 transportLogic = signalR.transports._logic,1667 createFrame = function () {1668 var frame = window.document.createElement("iframe");1669 frame.setAttribute("style", "position:absolute;top:0;left:0;width:0;height:0;visibility:hidden;");1670 return frame;1671 },1672 // Used to prevent infinite loading icon spins in older versions of ie1673 // We build this object inside a closure so we don't pollute the rest of1674 // the foreverFrame transport with unnecessary functions/utilities.1675 loadPreventer = (function () {1676 var loadingFixIntervalId = null,1677 loadingFixInterval = 1000,1678 attachedTo = 0;1679 return {1680 prevent: function () {1681 // Prevent additional iframe removal procedures from newer browsers1682 if (signalR._.ieVersion <= 8) {1683 // We only ever want to set the interval one time, so on the first attachedTo1684 if (attachedTo === 0) {1685 // Create and destroy iframe every 3 seconds to prevent loading icon, super hacky1686 loadingFixIntervalId = window.setInterval(function () {1687 var tempFrame = createFrame();1688 window.document.body.appendChild(tempFrame);1689 window.document.body.removeChild(tempFrame);1690 tempFrame = null;1691 }, loadingFixInterval);1692 }1693 attachedTo++;1694 }1695 },1696 cancel: function () {1697 // Only clear the interval if there's only one more object that the loadPreventer is attachedTo1698 if (attachedTo === 1) {1699 window.clearInterval(loadingFixIntervalId);1700 }1701 if (attachedTo > 0) {1702 attachedTo--;1703 }1704 }1705 };1706 })();1707 signalR.transports.foreverFrame = {1708 name: "foreverFrame",1709 supportsKeepAlive: function () {1710 return true;1711 },1712 // Added as a value here so we can create tests to verify functionality1713 iframeClearThreshold: 50,1714 start: function (connection, onSuccess, onFailed) {1715 var that = this,1716 frameId = (transportLogic.foreverFrame.count += 1),1717 url,1718 frame = createFrame(),1719 frameLoadHandler = function () {1720 connection.log("Forever frame iframe finished loading and is no longer receiving messages.");1721 if (!onFailed || !onFailed()) {1722 that.reconnect(connection);1723 }1724 };1725 if (window.EventSource) {1726 // If the browser supports SSE, don't use Forever Frame1727 if (onFailed) {1728 connection.log("Forever Frame is not supported by SignalR on browsers with SSE support.");1729 onFailed();1730 }1731 return;1732 }1733 frame.setAttribute("data-signalr-connection-id", connection.id);1734 // Start preventing loading icon1735 // This will only perform work if the loadPreventer is not attached to another connection.1736 loadPreventer.prevent();1737 // Build the url1738 url = transportLogic.getUrl(connection, this.name);1739 url += "&frameId=" + frameId;1740 // add frame to the document prior to setting URL to avoid caching issues.1741 window.document.documentElement.appendChild(frame);1742 connection.log("Binding to iframe's load event.");1743 if (frame.addEventListener) {1744 frame.addEventListener("load", frameLoadHandler, false);1745 } else if (frame.attachEvent) {1746 frame.attachEvent("onload", frameLoadHandler);1747 }1748 frame.src = url;1749 transportLogic.foreverFrame.connections[frameId] = connection;1750 connection.frame = frame;1751 connection.frameId = frameId;1752 if (onSuccess) {1753 connection.onSuccess = function () {1754 connection.log("Iframe transport started.");1755 onSuccess();1756 };1757 }1758 },1759 reconnect: function (connection) {1760 var that = this;1761 // Need to verify connection state and verify before the setTimeout occurs because an application sleep could occur during the setTimeout duration.1762 if (transportLogic.isConnectedOrReconnecting(connection) && transportLogic.verifyLastActive(connection)) {1763 window.setTimeout(function () {1764 // Verify that we're ok to reconnect.1765 if (!transportLogic.verifyLastActive(connection)) {1766 return;1767 }1768 if (connection.frame && transportLogic.ensureReconnectingState(connection)) {1769 var frame = connection.frame,1770 src = transportLogic.getUrl(connection, that.name, true) + "&frameId=" + connection.frameId;1771 connection.log("Updating iframe src to '" + src + "'.");1772 frame.src = src;1773 }1774 }, connection.reconnectDelay);1775 }1776 },1777 lostConnection: function (connection) {1778 this.reconnect(connection);1779 },1780 send: function (connection, data) {1781 transportLogic.ajaxSend(connection, data);1782 },1783 receive: function (connection, data) {1784 var cw,1785 body,1786 response;1787 if (connection.json !== connection._originalJson) {1788 // If there's a custom JSON parser configured then serialize the object1789 // using the original (browser) JSON parser and then deserialize it using1790 // the custom parser (connection._parseResponse does that). This is so we1791 // can easily send the response from the server as "raw" JSON but still1792 // support custom JSON deserialization in the browser.1793 data = connection._originalJson.stringify(data);1794 }1795 response = connection._parseResponse(data);1796 transportLogic.processMessages(connection, response, connection.onSuccess);1797 // Protect against connection stopping from a callback trigger within the processMessages above.1798 if (connection.state === $.signalR.connectionState.connected) {1799 // Delete the script & div elements1800 connection.frameMessageCount = (connection.frameMessageCount || 0) + 1;1801 if (connection.frameMessageCount > signalR.transports.foreverFrame.iframeClearThreshold) {1802 connection.frameMessageCount = 0;1803 cw = connection.frame.contentWindow || connection.frame.contentDocument;1804 if (cw && cw.document && cw.document.body) {1805 body = cw.document.body;1806 // Remove all the child elements from the iframe's body to conserver memory1807 while (body.firstChild) {1808 body.removeChild(body.firstChild);1809 }1810 }1811 }1812 }1813 },1814 stop: function (connection) {1815 var cw = null;1816 // Stop attempting to prevent loading icon1817 loadPreventer.cancel();1818 if (connection.frame) {1819 if (connection.frame.stop) {1820 connection.frame.stop();1821 } else {1822 try {1823 cw = connection.frame.contentWindow || connection.frame.contentDocument;1824 if (cw.document && cw.document.execCommand) {1825 cw.document.execCommand("Stop");1826 }1827 }1828 catch (e) {1829 connection.log("Error occurred when stopping foreverFrame transport. Message = " + e.message + ".");1830 }1831 }1832 // Ensure the iframe is where we left it1833 if (connection.frame.parentNode === window.document.documentElement) {1834 window.document.documentElement.removeChild(connection.frame);1835 }1836 delete transportLogic.foreverFrame.connections[connection.frameId];1837 connection.frame = null;1838 connection.frameId = null;1839 delete connection.frame;1840 delete connection.frameId;1841 delete connection.onSuccess;1842 delete connection.frameMessageCount;1843 connection.log("Stopping forever frame.");1844 }1845 },1846 abort: function (connection, async) {1847 transportLogic.ajaxAbort(connection, async);1848 },1849 getConnection: function (id) {1850 return transportLogic.foreverFrame.connections[id];1851 },1852 started: function (connection) {1853 if (changeState(connection,1854 signalR.connectionState.reconnecting,1855 signalR.connectionState.connected) === true) {1856 $(connection).triggerHandler(events.onReconnect);1857 }1858 }1859 };1860}(window.jQuery, window));1861/* jquery.signalR.transports.longPolling.js */1862// Copyright (c) .NET Foundation. All rights reserved.1863// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.1864/*global window:false */1865/// <reference path="jquery.signalR.transports.common.js" />1866(function ($, window, undefined) {1867 var signalR = $.signalR,1868 events = $.signalR.events,1869 changeState = $.signalR.changeState,1870 isDisconnecting = $.signalR.isDisconnecting,1871 transportLogic = signalR.transports._logic;1872 signalR.transports.longPolling = {1873 name: "longPolling",1874 supportsKeepAlive: function () {1875 return false;1876 },1877 reconnectDelay: 3000,1878 start: function (connection, onSuccess, onFailed) {1879 /// <summary>Starts the long polling connection</summary>1880 /// <param name="connection" type="signalR">The SignalR connection to start</param>1881 var that = this,1882 fireConnect = function () {1883 fireConnect = $.noop;1884 connection.log("LongPolling connected.");1885 if (onSuccess) {1886 onSuccess();1887 } else {1888 connection.log("WARNING! The client received an init message after reconnecting.");1889 }1890 },1891 tryFailConnect = function (error) {1892 if (onFailed(error)) {1893 connection.log("LongPolling failed to connect.");1894 return true;1895 }1896 return false;1897 },1898 privateData = connection._,1899 reconnectErrors = 0,1900 fireReconnected = function (instance) {1901 window.clearTimeout(privateData.reconnectTimeoutId);1902 privateData.reconnectTimeoutId = null;1903 if (changeState(instance,1904 signalR.connectionState.reconnecting,1905 signalR.connectionState.connected) === true) {1906 // Successfully reconnected!1907 instance.log("Raising the reconnect event");1908 $(instance).triggerHandler(events.onReconnect);1909 }1910 },1911 // 1 hour1912 maxFireReconnectedTimeout = 3600000;1913 if (connection.pollXhr) {1914 connection.log("Polling xhr requests already exists, aborting.");1915 connection.stop();1916 }1917 connection.messageId = null;1918 privateData.reconnectTimeoutId = null;1919 privateData.pollTimeoutId = window.setTimeout(function () {1920 (function poll(instance, raiseReconnect) {1921 var messageId = instance.messageId,1922 connect = (messageId === null),1923 reconnecting = !connect,1924 polling = !raiseReconnect,1925 url = transportLogic.getUrl(instance, that.name, reconnecting, polling, true /* use Post for longPolling */),1926 postData = {};1927 if (instance.messageId) {1928 postData.messageId = instance.messageId;1929 }1930 if (instance.groupsToken) {1931 postData.groupsToken = instance.groupsToken;1932 }1933 // If we've disconnected during the time we've tried to re-instantiate the poll then stop.1934 if (isDisconnecting(instance) === true) {1935 return;1936 }1937 connection.log("Opening long polling request to '" + url + "'.");1938 instance.pollXhr = transportLogic.ajax(connection, {1939 xhrFields: {1940 onprogress: function () {1941 transportLogic.markLastMessage(connection);1942 }1943 },1944 url: url,1945 type: "POST",1946 contentType: signalR._.defaultContentType,1947 data: postData,1948 timeout: connection._.pollTimeout,1949 success: function (result) {1950 var minData,1951 delay = 0,1952 data,1953 shouldReconnect;1954 connection.log("Long poll complete.");1955 // Reset our reconnect errors so if we transition into a reconnecting state again we trigger1956 // reconnected quickly1957 reconnectErrors = 0;1958 try {1959 // Remove any keep-alives from the beginning of the result1960 minData = connection._parseResponse(result);1961 }1962 catch (error) {1963 transportLogic.handleParseFailure(instance, result, error, tryFailConnect, instance.pollXhr);1964 return;1965 }1966 // If there's currently a timeout to trigger reconnect, fire it now before processing messages1967 if (privateData.reconnectTimeoutId !== null) {1968 fireReconnected(instance);1969 }1970 if (minData) {1971 data = transportLogic.maximizePersistentResponse(minData);1972 }1973 transportLogic.processMessages(instance, minData, fireConnect);1974 if (data &&1975 $.type(data.LongPollDelay) === "number") {1976 delay = data.LongPollDelay;1977 }1978 if (isDisconnecting(instance) === true) {1979 return;1980 }1981 shouldReconnect = data && data.ShouldReconnect;1982 if (shouldReconnect) {1983 // Transition into the reconnecting state1984 // If this fails then that means that the user transitioned the connection into a invalid state in processMessages.1985 if (!transportLogic.ensureReconnectingState(instance)) {1986 return;1987 }1988 }1989 // We never want to pass a raiseReconnect flag after a successful poll. This is handled via the error function1990 if (delay > 0) {1991 privateData.pollTimeoutId = window.setTimeout(function () {1992 poll(instance, shouldReconnect);1993 }, delay);1994 } else {1995 poll(instance, shouldReconnect);1996 }1997 },1998 error: function (data, textStatus) {1999 var error = signalR._.transportError(signalR.resources.longPollFailed, connection.transport, data, instance.pollXhr);2000 // Stop trying to trigger reconnect, connection is in an error state2001 // If we're not in the reconnect state this will noop2002 window.clearTimeout(privateData.reconnectTimeoutId);2003 privateData.reconnectTimeoutId = null;2004 if (textStatus === "abort") {2005 connection.log("Aborted xhr request.");2006 return;2007 }2008 if (!tryFailConnect(error)) {2009 // Increment our reconnect errors, we assume all errors to be reconnect errors2010 // In the case that it's our first error this will cause Reconnect to be fired2011 // after 1 second due to reconnectErrors being = 1.2012 reconnectErrors++;2013 if (connection.state !== signalR.connectionState.reconnecting) {2014 connection.log("An error occurred using longPolling. Status = " + textStatus + ". Response = " + data.responseText + ".");2015 $(instance).triggerHandler(events.onError, [error]);2016 }2017 // We check the state here to verify that we're not in an invalid state prior to verifying Reconnect.2018 // If we're not in connected or reconnecting then the next ensureReconnectingState check will fail and will return.2019 // Therefore we don't want to change that failure code path.2020 if ((connection.state === signalR.connectionState.connected ||2021 connection.state === signalR.connectionState.reconnecting) &&2022 !transportLogic.verifyLastActive(connection)) {2023 return;2024 }2025 // Transition into the reconnecting state2026 // If this fails then that means that the user transitioned the connection into the disconnected or connecting state within the above error handler trigger.2027 if (!transportLogic.ensureReconnectingState(instance)) {2028 return;2029 }2030 // Call poll with the raiseReconnect flag as true after the reconnect delay2031 privateData.pollTimeoutId = window.setTimeout(function () {2032 poll(instance, true);2033 }, that.reconnectDelay);2034 }2035 }2036 });2037 // This will only ever pass after an error has occurred via the poll ajax procedure.2038 if (reconnecting && raiseReconnect === true) {2039 // We wait to reconnect depending on how many times we've failed to reconnect.2040 // This is essentially a heuristic that will exponentially increase in wait time before2041 // triggering reconnected. This depends on the "error" handler of Poll to cancel this2042 // timeout if it triggers before the Reconnected event fires.2043 // The Math.min at the end is to ensure that the reconnect timeout does not overflow.2044 privateData.reconnectTimeoutId = window.setTimeout(function () { fireReconnected(instance); }, Math.min(1000 * (Math.pow(2, reconnectErrors) - 1), maxFireReconnectedTimeout));2045 }2046 }(connection));2047 }, 250); // Have to delay initial poll so Chrome doesn't show loader spinner in tab2048 },2049 lostConnection: function (connection) {2050 if (connection.pollXhr) {2051 connection.pollXhr.abort("lostConnection");2052 }2053 },2054 send: function (connection, data) {2055 transportLogic.ajaxSend(connection, data);2056 },2057 stop: function (connection) {2058 /// <summary>Stops the long polling connection</summary>2059 /// <param name="connection" type="signalR">The SignalR connection to stop</param>2060 window.clearTimeout(connection._.pollTimeoutId);2061 window.clearTimeout(connection._.reconnectTimeoutId);2062 delete connection._.pollTimeoutId;2063 delete connection._.reconnectTimeoutId;2064 if (connection.pollXhr) {2065 connection.pollXhr.abort();2066 connection.pollXhr = null;2067 delete connection.pollXhr;2068 }2069 },2070 abort: function (connection, async) {2071 transportLogic.ajaxAbort(connection, async);2072 }2073 };2074}(window.jQuery, window));2075/* jquery.signalR.hubs.js */2076// Copyright (c) .NET Foundation. All rights reserved.2077// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.2078/*global window:false */2079/// <reference path="jquery.signalR.core.js" />2080(function ($, window, undefined) {2081 var eventNamespace = ".hubProxy",2082 signalR = $.signalR;2083 function makeEventName(event) {2084 return event + eventNamespace;2085 }2086 // Equivalent to Array.prototype.map2087 function map(arr, fun, thisp) {2088 var i,2089 length = arr.length,2090 result = [];2091 for (i = 0; i < length; i += 1) {2092 if (arr.hasOwnProperty(i)) {2093 result[i] = fun.call(thisp, arr[i], i, arr);2094 }2095 }2096 return result;2097 }2098 function getArgValue(a) {2099 return $.isFunction(a) ? null : ($.type(a) === "undefined" ? null : a);2100 }2101 function hasMembers(obj) {2102 for (var key in obj) {2103 // If we have any properties in our callback map then we have callbacks and can exit the loop via return2104 if (obj.hasOwnProperty(key)) {2105 return true;2106 }2107 }2108 return false;2109 }2110 function clearInvocationCallbacks(connection, error) {2111 /// <param name="connection" type="hubConnection" />2112 var callbacks = connection._.invocationCallbacks,2113 callback;2114 if (hasMembers(callbacks)) {2115 connection.log("Clearing hub invocation callbacks with error: " + error + ".");2116 }2117 // Reset the callback cache now as we have a local var referencing it2118 connection._.invocationCallbackId = 0;2119 delete connection._.invocationCallbacks;2120 connection._.invocationCallbacks = {};2121 // Loop over the callbacks and invoke them.2122 // We do this using a local var reference and *after* we've cleared the cache2123 // so that if a fail callback itself tries to invoke another method we don't2124 // end up with its callback in the list we're looping over.2125 for (var callbackId in callbacks) {2126 callback = callbacks[callbackId];2127 callback.method.call(callback.scope, { E: error });2128 }2129 }2130 // hubProxy2131 function hubProxy(hubConnection, hubName) {2132 /// <summary>2133 /// Creates a new proxy object for the given hub connection that can be used to invoke2134 /// methods on server hubs and handle client method invocation requests from the server.2135 /// </summary>2136 return new hubProxy.fn.init(hubConnection, hubName);2137 }2138 hubProxy.fn = hubProxy.prototype = {2139 init: function (connection, hubName) {2140 this.state = {};2141 this.connection = connection;2142 this.hubName = hubName;2143 this._ = {2144 callbackMap: {}2145 };2146 },2147 constructor: hubProxy,2148 hasSubscriptions: function () {2149 return hasMembers(this._.callbackMap);2150 },2151 on: function (eventName, callback) {2152 /// <summary>Wires up a callback to be invoked when a invocation request is received from the server hub.</summary>2153 /// <param name="eventName" type="String">The name of the hub event to register the callback for.</param>2154 /// <param name="callback" type="Function">The callback to be invoked.</param>2155 var that = this,2156 callbackMap = that._.callbackMap;2157 // Normalize the event name to lowercase2158 eventName = eventName.toLowerCase();2159 // If there is not an event registered for this callback yet we want to create its event space in the callback map.2160 if (!callbackMap[eventName]) {2161 callbackMap[eventName] = {};2162 }2163 // Map the callback to our encompassed function2164 callbackMap[eventName][callback] = function (e, data) {2165 callback.apply(that, data);2166 };2167 $(that).bind(makeEventName(eventName), callbackMap[eventName][callback]);2168 return that;2169 },2170 off: function (eventName, callback) {2171 /// <summary>Removes the callback invocation request from the server hub for the given event name.</summary>2172 /// <param name="eventName" type="String">The name of the hub event to unregister the callback for.</param>2173 /// <param name="callback" type="Function">The callback to be invoked.</param>2174 var that = this,2175 callbackMap = that._.callbackMap,2176 callbackSpace;2177 // Normalize the event name to lowercase2178 eventName = eventName.toLowerCase();2179 callbackSpace = callbackMap[eventName];2180 // Verify that there is an event space to unbind2181 if (callbackSpace) {2182 // Only unbind if there's an event bound with eventName and a callback with the specified callback2183 if (callbackSpace[callback]) {2184 $(that).unbind(makeEventName(eventName), callbackSpace[callback]);2185 // Remove the callback from the callback map2186 delete callbackSpace[callback];2187 // Check if there are any members left on the event, if not we need to destroy it.2188 if (!hasMembers(callbackSpace)) {2189 delete callbackMap[eventName];2190 }2191 } else if (!callback) { // Check if we're removing the whole event and we didn't error because of an invalid callback2192 $(that).unbind(makeEventName(eventName));2193 delete callbackMap[eventName];2194 }2195 }2196 return that;2197 },2198 invoke: function (methodName) {2199 /// <summary>Invokes a server hub method with the given arguments.</summary>2200 /// <param name="methodName" type="String">The name of the server hub method.</param>2201 var that = this,2202 connection = that.connection,2203 args = $.makeArray(arguments).slice(1),2204 argValues = map(args, getArgValue),2205 data = { H: that.hubName, M: methodName, A: argValues, I: connection._.invocationCallbackId },2206 d = $.Deferred(),2207 callback = function (minResult) {2208 var result = that._maximizeHubResponse(minResult),2209 source,2210 error;2211 // Update the hub state2212 $.extend(that.state, result.State);2213 if (result.Progress) {2214 if (d.notifyWith) {2215 // Progress is only supported in jQuery 1.7+2216 d.notifyWith(that, [result.Progress.Data]);2217 } else if(!connection._.progressjQueryVersionLogged) {2218 connection.log("A hub method invocation progress update was received but the version of jQuery in use (" + $.prototype.jquery + ") does not support progress updates. Upgrade to jQuery 1.7+ to receive progress notifications.");2219 connection._.progressjQueryVersionLogged = true;2220 }2221 } else if (result.Error) {2222 // Server hub method threw an exception, log it & reject the deferred2223 if (result.StackTrace) {2224 connection.log(result.Error + "\n" + result.StackTrace + ".");2225 }2226 // result.ErrorData is only set if a HubException was thrown2227 source = result.IsHubException ? "HubException" : "Exception";2228 error = signalR._.error(result.Error, source);2229 error.data = result.ErrorData;2230 connection.log(that.hubName + "." + methodName + " failed to execute. Error: " + error.message);2231 d.rejectWith(that, [error]);2232 } else {2233 // Server invocation succeeded, resolve the deferred2234 connection.log("Invoked " + that.hubName + "." + methodName);2235 d.resolveWith(that, [result.Result]);2236 }2237 };2238 connection._.invocationCallbacks[connection._.invocationCallbackId.toString()] = { scope: that, method: callback };2239 connection._.invocationCallbackId += 1;2240 if (!$.isEmptyObject(that.state)) {2241 data.S = that.state;2242 }2243 connection.log("Invoking " + that.hubName + "." + methodName);2244 connection.send(data);2245 return d.promise();2246 },2247 _maximizeHubResponse: function (minHubResponse) {2248 return {2249 State: minHubResponse.S,2250 Result: minHubResponse.R,2251 Progress: minHubResponse.P ? {2252 Id: minHubResponse.P.I,2253 Data: minHubResponse.P.D2254 } : null,2255 Id: minHubResponse.I,2256 IsHubException: minHubResponse.H,2257 Error: minHubResponse.E,2258 StackTrace: minHubResponse.T,2259 ErrorData: minHubResponse.D2260 };2261 }2262 };2263 hubProxy.fn.init.prototype = hubProxy.fn;2264 // hubConnection2265 function hubConnection(url, options) {2266 /// <summary>Creates a new hub connection.</summary>2267 /// <param name="url" type="String">[Optional] The hub route url, defaults to "/signalr".</param>2268 /// <param name="options" type="Object">[Optional] Settings to use when creating the hubConnection.</param>2269 var settings = {2270 qs: null,2271 logging: false,2272 useDefaultPath: true2273 };2274 $.extend(settings, options);2275 if (!url || settings.useDefaultPath) {2276 url = (url || "") + "/signalr";2277 }2278 return new hubConnection.fn.init(url, settings);2279 }...
jquery.signalR-2.2.1.js
Source:jquery.signalR-2.2.1.js
...835 // Check if the keep alive has completely timed out836 if (timeElapsed >= keepAliveData.timeout) {837 connection.log("Keep alive timed out. Notifying transport that connection has been lost.");838 // Notify transport that the connection has been lost839 connection.transport.lostConnection(connection);840 } else if (timeElapsed >= keepAliveData.timeoutWarning) {841 // This is to assure that the user only gets a single warning842 if (!keepAliveData.userNotified) {843 connection.log("Keep alive has been missed, connection may be dead/slow.");844 $(connection).triggerHandler(events.onConnectionSlow);845 keepAliveData.userNotified = true;846 }847 } else {848 keepAliveData.userNotified = false;849 }850 }851 }852 function getAjaxUrl(connection, path) {853 var url = connection.url + path;854 if (connection.transport) {855 url += "?transport=" + connection.transport.name;856 }857 return transportLogic.prepareQueryString(connection, url);858 }859 function InitHandler(connection) {860 this.connection = connection;861 this.startRequested = false;862 this.startCompleted = false;863 this.connectionStopped = false;864 }865 InitHandler.prototype = {866 start: function (transport, onSuccess, onFallback) {867 var that = this,868 connection = that.connection,869 failCalled = false;870 if (that.startRequested || that.connectionStopped) {871 connection.log("WARNING! " + transport.name + " transport cannot be started. Initialization ongoing or completed.");872 return;873 }874 connection.log(transport.name + " transport starting.");875 transport.start(connection, function () {876 if (!failCalled) {877 that.initReceived(transport, onSuccess);878 }879 }, function (error) {880 // Don't allow the same transport to cause onFallback to be called twice881 if (!failCalled) {882 failCalled = true;883 that.transportFailed(transport, error, onFallback);884 }885 // Returns true if the transport should stop;886 // false if it should attempt to reconnect887 return !that.startCompleted || that.connectionStopped;888 });889 that.transportTimeoutHandle = window.setTimeout(function () {890 if (!failCalled) {891 failCalled = true;892 connection.log(transport.name + " transport timed out when trying to connect.");893 that.transportFailed(transport, undefined, onFallback);894 }895 }, connection._.totalTransportConnectTimeout);896 },897 stop: function () {898 this.connectionStopped = true;899 window.clearTimeout(this.transportTimeoutHandle);900 signalR.transports._logic.tryAbortStartRequest(this.connection);901 },902 initReceived: function (transport, onSuccess) {903 var that = this,904 connection = that.connection;905 if (that.startRequested) {906 connection.log("WARNING! The client received multiple init messages.");907 return;908 }909 if (that.connectionStopped) {910 return;911 }912 that.startRequested = true;913 window.clearTimeout(that.transportTimeoutHandle);914 connection.log(transport.name + " transport connected. Initiating start request.");915 signalR.transports._logic.ajaxStart(connection, function () {916 that.startCompleted = true;917 onSuccess();918 });919 },920 transportFailed: function (transport, error, onFallback) {921 var connection = this.connection,922 deferred = connection._deferral,923 wrappedError;924 if (this.connectionStopped) {925 return;926 }927 window.clearTimeout(this.transportTimeoutHandle);928 if (!this.startRequested) {929 transport.stop(connection);930 connection.log(transport.name + " transport failed to connect. Attempting to fall back.");931 onFallback();932 } else if (!this.startCompleted) {933 // Do not attempt to fall back if a start request is ongoing during a transport failure.934 // Instead, trigger an error and stop the connection.935 wrappedError = signalR._.error(signalR.resources.errorDuringStartRequest, error);936 connection.log(transport.name + " transport failed during the start request. Stopping the connection.");937 $(connection).triggerHandler(events.onError, [wrappedError]);938 if (deferred) {939 deferred.reject(wrappedError);940 }941 connection.stop();942 } else {943 // The start request has completed, but the connection has not stopped.944 // No need to do anything here. The transport should attempt its normal reconnect logic.945 }946 }947 };948 transportLogic = signalR.transports._logic = {949 ajax: function (connection, options) {950 return $.ajax(951 $.extend(/*deep copy*/ true, {}, $.signalR.ajaxDefaults, {952 type: "GET",953 data: {},954 xhrFields: { withCredentials: connection.withCredentials },955 contentType: connection.contentType,956 dataType: connection.ajaxDataType957 }, options));958 },959 pingServer: function (connection) {960 /// <summary>Pings the server</summary>961 /// <param name="connection" type="signalr">Connection associated with the server ping</param>962 /// <returns type="signalR" />963 var url,964 xhr,965 deferral = $.Deferred();966 if (connection.transport) {967 url = connection.url + "/ping";968 url = transportLogic.addQs(url, connection.qs);969 xhr = transportLogic.ajax(connection, {970 url: url,971 success: function (result) {972 var data;973 try {974 data = connection._parseResponse(result);975 }976 catch (error) {977 deferral.reject(978 signalR._.transportError(979 signalR.resources.pingServerFailedParse,980 connection.transport,981 error,982 xhr983 )984 );985 connection.stop();986 return;987 }988 if (data.Response === "pong") {989 deferral.resolve();990 }991 else {992 deferral.reject(993 signalR._.transportError(994 signalR._.format(signalR.resources.pingServerFailedInvalidResponse, result),995 connection.transport,996 null /* error */,997 xhr998 )999 );1000 }1001 },1002 error: function (error) {1003 if (error.status === 401 || error.status === 403) {1004 deferral.reject(1005 signalR._.transportError(1006 signalR._.format(signalR.resources.pingServerFailedStatusCode, error.status),1007 connection.transport,1008 error,1009 xhr1010 )1011 );1012 connection.stop();1013 }1014 else {1015 deferral.reject(1016 signalR._.transportError(1017 signalR.resources.pingServerFailed,1018 connection.transport,1019 error,1020 xhr1021 )1022 );1023 }1024 }1025 });1026 }1027 else {1028 deferral.reject(1029 signalR._.transportError(1030 signalR.resources.noConnectionTransport,1031 connection.transport1032 )1033 );1034 }1035 return deferral.promise();1036 },1037 prepareQueryString: function (connection, url) {1038 var preparedUrl;1039 // Use addQs to start since it handles the ?/& prefix for us1040 preparedUrl = transportLogic.addQs(url, "clientProtocol=" + connection.clientProtocol);1041 // Add the user-specified query string params if any1042 preparedUrl = transportLogic.addQs(preparedUrl, connection.qs);1043 if (connection.token) {1044 preparedUrl += "&connectionToken=" + window.encodeURIComponent(connection.token);1045 }1046 if (connection.data) {1047 preparedUrl += "&connectionData=" + window.encodeURIComponent(connection.data);1048 }1049 return preparedUrl;1050 },1051 addQs: function (url, qs) {1052 var appender = url.indexOf("?") !== -1 ? "&" : "?",1053 firstChar;1054 if (!qs) {1055 return url;1056 }1057 if (typeof (qs) === "object") {1058 return url + appender + $.param(qs);1059 }1060 if (typeof (qs) === "string") {1061 firstChar = qs.charAt(0);1062 if (firstChar === "?" || firstChar === "&") {1063 appender = "";1064 }1065 return url + appender + qs;1066 }1067 throw new Error("Query string property must be either a string or object.");1068 },1069 // BUG #2953: The url needs to be same otherwise it will cause a memory leak1070 getUrl: function (connection, transport, reconnecting, poll, ajaxPost) {1071 /// <summary>Gets the url for making a GET based connect request</summary>1072 var baseUrl = transport === "webSockets" ? "" : connection.baseUrl,1073 url = baseUrl + connection.appRelativeUrl,1074 qs = "transport=" + transport;1075 if (!ajaxPost && connection.groupsToken) {1076 qs += "&groupsToken=" + window.encodeURIComponent(connection.groupsToken);1077 }1078 if (!reconnecting) {1079 url += "/connect";1080 } else {1081 if (poll) {1082 // longPolling transport specific1083 url += "/poll";1084 } else {1085 url += "/reconnect";1086 }1087 if (!ajaxPost && connection.messageId) {1088 qs += "&messageId=" + window.encodeURIComponent(connection.messageId);1089 }1090 }1091 url += "?" + qs;1092 url = transportLogic.prepareQueryString(connection, url);1093 if (!ajaxPost) {1094 url += "&tid=" + Math.floor(Math.random() * 11);1095 }1096 return url;1097 },1098 maximizePersistentResponse: function (minPersistentResponse) {1099 return {1100 MessageId: minPersistentResponse.C,1101 Messages: minPersistentResponse.M,1102 Initialized: typeof (minPersistentResponse.S) !== "undefined" ? true : false,1103 ShouldReconnect: typeof (minPersistentResponse.T) !== "undefined" ? true : false,1104 LongPollDelay: minPersistentResponse.L,1105 GroupsToken: minPersistentResponse.G1106 };1107 },1108 updateGroups: function (connection, groupsToken) {1109 if (groupsToken) {1110 connection.groupsToken = groupsToken;1111 }1112 },1113 stringifySend: function (connection, message) {1114 if (typeof (message) === "string" || typeof (message) === "undefined" || message === null) {1115 return message;1116 }1117 return connection.json.stringify(message);1118 },1119 ajaxSend: function (connection, data) {1120 var payload = transportLogic.stringifySend(connection, data),1121 url = getAjaxUrl(connection, "/send"),1122 xhr,1123 onFail = function (error, connection) {1124 $(connection).triggerHandler(events.onError, [signalR._.transportError(signalR.resources.sendFailed, connection.transport, error, xhr), data]);1125 };1126 xhr = transportLogic.ajax(connection, {1127 url: url,1128 type: connection.ajaxDataType === "jsonp" ? "GET" : "POST",1129 contentType: signalR._.defaultContentType,1130 data: {1131 data: payload1132 },1133 success: function (result) {1134 var res;1135 if (result) {1136 try {1137 res = connection._parseResponse(result);1138 }1139 catch (error) {1140 onFail(error, connection);1141 connection.stop();1142 return;1143 }1144 transportLogic.triggerReceived(connection, res);1145 }1146 },1147 error: function (error, textStatus) {1148 if (textStatus === "abort" || textStatus === "parsererror") {1149 // The parsererror happens for sends that don't return any data, and hence1150 // don't write the jsonp callback to the response. This is harder to fix on the server1151 // so just hack around it on the client for now.1152 return;1153 }1154 onFail(error, connection);1155 }1156 });1157 return xhr;1158 },1159 ajaxAbort: function (connection, async) {1160 if (typeof (connection.transport) === "undefined") {1161 return;1162 }1163 // Async by default unless explicitly overidden1164 async = typeof async === "undefined" ? true : async;1165 var url = getAjaxUrl(connection, "/abort");1166 transportLogic.ajax(connection, {1167 url: url,1168 async: async,1169 timeout: 1000,1170 type: "POST"1171 });1172 connection.log("Fired ajax abort async = " + async + ".");1173 },1174 ajaxStart: function (connection, onSuccess) {1175 var rejectDeferred = function (error) {1176 var deferred = connection._deferral;1177 if (deferred) {1178 deferred.reject(error);1179 }1180 },1181 triggerStartError = function (error) {1182 connection.log("The start request failed. Stopping the connection.");1183 $(connection).triggerHandler(events.onError, [error]);1184 rejectDeferred(error);1185 connection.stop();1186 };1187 connection._.startRequest = transportLogic.ajax(connection, {1188 url: getAjaxUrl(connection, "/start"),1189 success: function (result, statusText, xhr) {1190 var data;1191 try {1192 data = connection._parseResponse(result);1193 } catch (error) {1194 triggerStartError(signalR._.error(1195 signalR._.format(signalR.resources.errorParsingStartResponse, result),1196 error, xhr));1197 return;1198 }1199 if (data.Response === "started") {1200 onSuccess();1201 } else {1202 triggerStartError(signalR._.error(1203 signalR._.format(signalR.resources.invalidStartResponse, result),1204 null /* error */, xhr));1205 }1206 },1207 error: function (xhr, statusText, error) {1208 if (statusText !== startAbortText) {1209 triggerStartError(signalR._.error(1210 signalR.resources.errorDuringStartRequest,1211 error, xhr));1212 } else {1213 // Stop has been called, no need to trigger the error handler1214 // or stop the connection again with onStartError1215 connection.log("The start request aborted because connection.stop() was called.");1216 rejectDeferred(signalR._.error(1217 signalR.resources.stoppedDuringStartRequest,1218 null /* error */, xhr));1219 }1220 }1221 });1222 },1223 tryAbortStartRequest: function (connection) {1224 if (connection._.startRequest) {1225 // If the start request has already completed this will noop.1226 connection._.startRequest.abort(startAbortText);1227 delete connection._.startRequest;1228 }1229 },1230 tryInitialize: function (connection, persistentResponse, onInitialized) {1231 if (persistentResponse.Initialized && onInitialized) {1232 onInitialized();1233 } else if (persistentResponse.Initialized) {1234 connection.log("WARNING! The client received an init message after reconnecting.");1235 }1236 },1237 triggerReceived: function (connection, data) {1238 if (!connection._.connectingMessageBuffer.tryBuffer(data)) {1239 $(connection).triggerHandler(events.onReceived, [data]);1240 }1241 },1242 processMessages: function (connection, minData, onInitialized) {1243 var data;1244 // Update the last message time stamp1245 transportLogic.markLastMessage(connection);1246 if (minData) {1247 data = transportLogic.maximizePersistentResponse(minData);1248 transportLogic.updateGroups(connection, data.GroupsToken);1249 if (data.MessageId) {1250 connection.messageId = data.MessageId;1251 }1252 if (data.Messages) {1253 $.each(data.Messages, function (index, message) {1254 transportLogic.triggerReceived(connection, message);1255 });1256 transportLogic.tryInitialize(connection, data, onInitialized);1257 }1258 }1259 },1260 monitorKeepAlive: function (connection) {1261 var keepAliveData = connection._.keepAliveData;1262 // If we haven't initiated the keep alive timeouts then we need to1263 if (!keepAliveData.monitoring) {1264 keepAliveData.monitoring = true;1265 transportLogic.markLastMessage(connection);1266 // Save the function so we can unbind it on stop1267 connection._.keepAliveData.reconnectKeepAliveUpdate = function () {1268 // Mark a new message so that keep alive doesn't time out connections1269 transportLogic.markLastMessage(connection);1270 };1271 // Update Keep alive on reconnect1272 $(connection).bind(events.onReconnect, connection._.keepAliveData.reconnectKeepAliveUpdate);1273 connection.log("Now monitoring keep alive with a warning timeout of " + keepAliveData.timeoutWarning + ", keep alive timeout of " + keepAliveData.timeout + " and disconnecting timeout of " + connection.disconnectTimeout);1274 } else {1275 connection.log("Tried to monitor keep alive but it's already being monitored.");1276 }1277 },1278 stopMonitoringKeepAlive: function (connection) {1279 var keepAliveData = connection._.keepAliveData;1280 // Only attempt to stop the keep alive monitoring if its being monitored1281 if (keepAliveData.monitoring) {1282 // Stop monitoring1283 keepAliveData.monitoring = false;1284 // Remove the updateKeepAlive function from the reconnect event1285 $(connection).unbind(events.onReconnect, connection._.keepAliveData.reconnectKeepAliveUpdate);1286 // Clear all the keep alive data1287 connection._.keepAliveData = {};1288 connection.log("Stopping the monitoring of the keep alive.");1289 }1290 },1291 startHeartbeat: function (connection) {1292 connection._.lastActiveAt = new Date().getTime();1293 beat(connection);1294 },1295 markLastMessage: function (connection) {1296 connection._.lastMessageAt = new Date().getTime();1297 },1298 markActive: function (connection) {1299 if (transportLogic.verifyLastActive(connection)) {1300 connection._.lastActiveAt = new Date().getTime();1301 return true;1302 }1303 return false;1304 },1305 isConnectedOrReconnecting: function (connection) {1306 return connection.state === signalR.connectionState.connected ||1307 connection.state === signalR.connectionState.reconnecting;1308 },1309 ensureReconnectingState: function (connection) {1310 if (changeState(connection,1311 signalR.connectionState.connected,1312 signalR.connectionState.reconnecting) === true) {1313 $(connection).triggerHandler(events.onReconnecting);1314 }1315 return connection.state === signalR.connectionState.reconnecting;1316 },1317 clearReconnectTimeout: function (connection) {1318 if (connection && connection._.reconnectTimeout) {1319 window.clearTimeout(connection._.reconnectTimeout);1320 delete connection._.reconnectTimeout;1321 }1322 },1323 verifyLastActive: function (connection) {1324 if (new Date().getTime() - connection._.lastActiveAt >= connection.reconnectWindow) {1325 var message = signalR._.format(signalR.resources.reconnectWindowTimeout, new Date(connection._.lastActiveAt), connection.reconnectWindow);1326 connection.log(message);1327 $(connection).triggerHandler(events.onError, [signalR._.error(message, /* source */ "TimeoutException")]);1328 connection.stop(/* async */ false, /* notifyServer */ false);1329 return false;1330 }1331 return true;1332 },1333 reconnect: function (connection, transportName) {1334 var transport = signalR.transports[transportName];1335 // We should only set a reconnectTimeout if we are currently connected1336 // and a reconnectTimeout isn't already set.1337 if (transportLogic.isConnectedOrReconnecting(connection) && !connection._.reconnectTimeout) {1338 // Need to verify before the setTimeout occurs because an application sleep could occur during the setTimeout duration.1339 if (!transportLogic.verifyLastActive(connection)) {1340 return;1341 }1342 connection._.reconnectTimeout = window.setTimeout(function () {1343 if (!transportLogic.verifyLastActive(connection)) {1344 return;1345 }1346 transport.stop(connection);1347 if (transportLogic.ensureReconnectingState(connection)) {1348 connection.log(transportName + " reconnecting.");1349 transport.start(connection);1350 }1351 }, connection.reconnectDelay);1352 }1353 },1354 handleParseFailure: function (connection, result, error, onFailed, context) {1355 var wrappedError = signalR._.transportError(1356 signalR._.format(signalR.resources.parseFailed, result),1357 connection.transport,1358 error,1359 context);1360 // If we're in the initialization phase trigger onFailed, otherwise stop the connection.1361 if (onFailed && onFailed(wrappedError)) {1362 connection.log("Failed to parse server response while attempting to connect.");1363 } else {1364 $(connection).triggerHandler(events.onError, [wrappedError]);1365 connection.stop();1366 }1367 },1368 initHandler: function (connection) {1369 return new InitHandler(connection);1370 },1371 foreverFrame: {1372 count: 0,1373 connections: {}1374 }1375 };1376}(window.jQuery, window));1377/* jquery.signalR.transports.webSockets.js */1378// Copyright (c) .NET Foundation. All rights reserved.1379// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.1380/*global window:false */1381/// <reference path="jquery.signalR.transports.common.js" />1382(function ($, window, undefined) {1383 var signalR = $.signalR,1384 events = $.signalR.events,1385 changeState = $.signalR.changeState,1386 transportLogic = signalR.transports._logic;1387 signalR.transports.webSockets = {1388 name: "webSockets",1389 supportsKeepAlive: function () {1390 return true;1391 },1392 send: function (connection, data) {1393 var payload = transportLogic.stringifySend(connection, data);1394 try {1395 connection.socket.send(payload);1396 } catch (ex) {1397 $(connection).triggerHandler(events.onError,1398 [signalR._.transportError(1399 signalR.resources.webSocketsInvalidState,1400 connection.transport,1401 ex,1402 connection.socket1403 ),1404 data]);1405 }1406 },1407 start: function (connection, onSuccess, onFailed) {1408 var url,1409 opened = false,1410 that = this,1411 reconnecting = !onSuccess,1412 $connection = $(connection);1413 if (!window.WebSocket) {1414 onFailed();1415 return;1416 }1417 if (!connection.socket) {1418 if (connection.webSocketServerUrl) {1419 url = connection.webSocketServerUrl;1420 } else {1421 url = connection.wsProtocol + connection.host;1422 }1423 url += transportLogic.getUrl(connection, this.name, reconnecting);1424 connection.log("Connecting to websocket endpoint '" + url + "'.");1425 connection.socket = new window.WebSocket(url);1426 connection.socket.onopen = function () {1427 opened = true;1428 connection.log("Websocket opened.");1429 transportLogic.clearReconnectTimeout(connection);1430 if (changeState(connection,1431 signalR.connectionState.reconnecting,1432 signalR.connectionState.connected) === true) {1433 $connection.triggerHandler(events.onReconnect);1434 }1435 };1436 connection.socket.onclose = function (event) {1437 var error;1438 // Only handle a socket close if the close is from the current socket.1439 // Sometimes on disconnect the server will push down an onclose event1440 // to an expired socket.1441 if (this === connection.socket) {1442 if (opened && typeof event.wasClean !== "undefined" && event.wasClean === false) {1443 // Ideally this would use the websocket.onerror handler (rather than checking wasClean in onclose) but1444 // I found in some circumstances Chrome won't call onerror. This implementation seems to work on all browsers.1445 error = signalR._.transportError(1446 signalR.resources.webSocketClosed,1447 connection.transport,1448 event);1449 connection.log("Unclean disconnect from websocket: " + (event.reason || "[no reason given]."));1450 } else {1451 connection.log("Websocket closed.");1452 }1453 if (!onFailed || !onFailed(error)) {1454 if (error) {1455 $(connection).triggerHandler(events.onError, [error]);1456 }1457 that.reconnect(connection);1458 }1459 }1460 };1461 connection.socket.onmessage = function (event) {1462 var data;1463 try {1464 data = connection._parseResponse(event.data);1465 }1466 catch (error) {1467 transportLogic.handleParseFailure(connection, event.data, error, onFailed, event);1468 return;1469 }1470 if (data) {1471 // data.M is PersistentResponse.Messages1472 if ($.isEmptyObject(data) || data.M) {1473 transportLogic.processMessages(connection, data, onSuccess);1474 } else {1475 // For websockets we need to trigger onReceived1476 // for callbacks to outgoing hub calls.1477 transportLogic.triggerReceived(connection, data);1478 }1479 }1480 };1481 }1482 },1483 reconnect: function (connection) {1484 transportLogic.reconnect(connection, this.name);1485 },1486 lostConnection: function (connection) {1487 this.reconnect(connection);1488 },1489 stop: function (connection) {1490 // Don't trigger a reconnect after stopping1491 transportLogic.clearReconnectTimeout(connection);1492 if (connection.socket) {1493 connection.log("Closing the Websocket.");1494 connection.socket.close();1495 connection.socket = null;1496 }1497 },1498 abort: function (connection, async) {1499 transportLogic.ajaxAbort(connection, async);1500 }1501 };1502}(window.jQuery, window));1503/* jquery.signalR.transports.serverSentEvents.js */1504// Copyright (c) .NET Foundation. All rights reserved.1505// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.1506/*global window:false */1507/// <reference path="jquery.signalR.transports.common.js" />1508(function ($, window, undefined) {1509 var signalR = $.signalR,1510 events = $.signalR.events,1511 changeState = $.signalR.changeState,1512 transportLogic = signalR.transports._logic,1513 clearReconnectAttemptTimeout = function (connection) {1514 window.clearTimeout(connection._.reconnectAttemptTimeoutHandle);1515 delete connection._.reconnectAttemptTimeoutHandle;1516 };1517 signalR.transports.serverSentEvents = {1518 name: "serverSentEvents",1519 supportsKeepAlive: function () {1520 return true;1521 },1522 timeOut: 3000,1523 start: function (connection, onSuccess, onFailed) {1524 var that = this,1525 opened = false,1526 $connection = $(connection),1527 reconnecting = !onSuccess,1528 url;1529 if (connection.eventSource) {1530 connection.log("The connection already has an event source. Stopping it.");1531 connection.stop();1532 }1533 if (!window.EventSource) {1534 if (onFailed) {1535 connection.log("This browser doesn't support SSE.");1536 onFailed();1537 }1538 return;1539 }1540 url = transportLogic.getUrl(connection, this.name, reconnecting);1541 try {1542 connection.log("Attempting to connect to SSE endpoint '" + url + "'.");1543 connection.eventSource = new window.EventSource(url, { withCredentials: connection.withCredentials });1544 }1545 catch (e) {1546 connection.log("EventSource failed trying to connect with error " + e.Message + ".");1547 if (onFailed) {1548 // The connection failed, call the failed callback1549 onFailed();1550 } else {1551 $connection.triggerHandler(events.onError, [signalR._.transportError(signalR.resources.eventSourceFailedToConnect, connection.transport, e)]);1552 if (reconnecting) {1553 // If we were reconnecting, rather than doing initial connect, then try reconnect again1554 that.reconnect(connection);1555 }1556 }1557 return;1558 }1559 if (reconnecting) {1560 connection._.reconnectAttemptTimeoutHandle = window.setTimeout(function () {1561 if (opened === false) {1562 // If we're reconnecting and the event source is attempting to connect,1563 // don't keep retrying. This causes duplicate connections to spawn.1564 if (connection.eventSource.readyState !== window.EventSource.OPEN) {1565 // If we were reconnecting, rather than doing initial connect, then try reconnect again1566 that.reconnect(connection);1567 }1568 }1569 },1570 that.timeOut);1571 }1572 connection.eventSource.addEventListener("open", function (e) {1573 connection.log("EventSource connected.");1574 clearReconnectAttemptTimeout(connection);1575 transportLogic.clearReconnectTimeout(connection);1576 if (opened === false) {1577 opened = true;1578 if (changeState(connection,1579 signalR.connectionState.reconnecting,1580 signalR.connectionState.connected) === true) {1581 $connection.triggerHandler(events.onReconnect);1582 }1583 }1584 }, false);1585 connection.eventSource.addEventListener("message", function (e) {1586 var res;1587 // process messages1588 if (e.data === "initialized") {1589 return;1590 }1591 try {1592 res = connection._parseResponse(e.data);1593 }1594 catch (error) {1595 transportLogic.handleParseFailure(connection, e.data, error, onFailed, e);1596 return;1597 }1598 transportLogic.processMessages(connection, res, onSuccess);1599 }, false);1600 connection.eventSource.addEventListener("error", function (e) {1601 var error = signalR._.transportError(1602 signalR.resources.eventSourceError,1603 connection.transport,1604 e);1605 // Only handle an error if the error is from the current Event Source.1606 // Sometimes on disconnect the server will push down an error event1607 // to an expired Event Source.1608 if (this !== connection.eventSource) {1609 return;1610 }1611 if (onFailed && onFailed(error)) {1612 return;1613 }1614 connection.log("EventSource readyState: " + connection.eventSource.readyState + ".");1615 if (e.eventPhase === window.EventSource.CLOSED) {1616 // We don't use the EventSource's native reconnect function as it1617 // doesn't allow us to change the URL when reconnecting. We need1618 // to change the URL to not include the /connect suffix, and pass1619 // the last message id we received.1620 connection.log("EventSource reconnecting due to the server connection ending.");1621 that.reconnect(connection);1622 } else {1623 // connection error1624 connection.log("EventSource error.");1625 $connection.triggerHandler(events.onError, [error]);1626 }1627 }, false);1628 },1629 reconnect: function (connection) {1630 transportLogic.reconnect(connection, this.name);1631 },1632 lostConnection: function (connection) {1633 this.reconnect(connection);1634 },1635 send: function (connection, data) {1636 transportLogic.ajaxSend(connection, data);1637 },1638 stop: function (connection) {1639 // Don't trigger a reconnect after stopping1640 clearReconnectAttemptTimeout(connection);1641 transportLogic.clearReconnectTimeout(connection);1642 if (connection && connection.eventSource) {1643 connection.log("EventSource calling close().");1644 connection.eventSource.close();1645 connection.eventSource = null;1646 delete connection.eventSource;1647 }1648 },1649 abort: function (connection, async) {1650 transportLogic.ajaxAbort(connection, async);1651 }1652 };1653}(window.jQuery, window));1654/* jquery.signalR.transports.foreverFrame.js */1655// Copyright (c) .NET Foundation. All rights reserved.1656// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.1657/*global window:false */1658/// <reference path="jquery.signalR.transports.common.js" />1659(function ($, window, undefined) {1660 var signalR = $.signalR,1661 events = $.signalR.events,1662 changeState = $.signalR.changeState,1663 transportLogic = signalR.transports._logic,1664 createFrame = function () {1665 var frame = window.document.createElement("iframe");1666 frame.setAttribute("style", "position:absolute;top:0;left:0;width:0;height:0;visibility:hidden;");1667 return frame;1668 },1669 // Used to prevent infinite loading icon spins in older versions of ie1670 // We build this object inside a closure so we don't pollute the rest of1671 // the foreverFrame transport with unnecessary functions/utilities.1672 loadPreventer = (function () {1673 var loadingFixIntervalId = null,1674 loadingFixInterval = 1000,1675 attachedTo = 0;1676 return {1677 prevent: function () {1678 // Prevent additional iframe removal procedures from newer browsers1679 if (signalR._.ieVersion <= 8) {1680 // We only ever want to set the interval one time, so on the first attachedTo1681 if (attachedTo === 0) {1682 // Create and destroy iframe every 3 seconds to prevent loading icon, super hacky1683 loadingFixIntervalId = window.setInterval(function () {1684 var tempFrame = createFrame();1685 window.document.body.appendChild(tempFrame);1686 window.document.body.removeChild(tempFrame);1687 tempFrame = null;1688 }, loadingFixInterval);1689 }1690 attachedTo++;1691 }1692 },1693 cancel: function () {1694 // Only clear the interval if there's only one more object that the loadPreventer is attachedTo1695 if (attachedTo === 1) {1696 window.clearInterval(loadingFixIntervalId);1697 }1698 if (attachedTo > 0) {1699 attachedTo--;1700 }1701 }1702 };1703 })();1704 signalR.transports.foreverFrame = {1705 name: "foreverFrame",1706 supportsKeepAlive: function () {1707 return true;1708 },1709 // Added as a value here so we can create tests to verify functionality1710 iframeClearThreshold: 50,1711 start: function (connection, onSuccess, onFailed) {1712 var that = this,1713 frameId = (transportLogic.foreverFrame.count += 1),1714 url,1715 frame = createFrame(),1716 frameLoadHandler = function () {1717 connection.log("Forever frame iframe finished loading and is no longer receiving messages.");1718 if (!onFailed || !onFailed()) {1719 that.reconnect(connection);1720 }1721 };1722 if (window.EventSource) {1723 // If the browser supports SSE, don't use Forever Frame1724 if (onFailed) {1725 connection.log("Forever Frame is not supported by SignalR on browsers with SSE support.");1726 onFailed();1727 }1728 return;1729 }1730 frame.setAttribute("data-signalr-connection-id", connection.id);1731 // Start preventing loading icon1732 // This will only perform work if the loadPreventer is not attached to another connection.1733 loadPreventer.prevent();1734 // Build the url1735 url = transportLogic.getUrl(connection, this.name);1736 url += "&frameId=" + frameId;1737 // add frame to the document prior to setting URL to avoid caching issues.1738 window.document.documentElement.appendChild(frame);1739 connection.log("Binding to iframe's load event.");1740 if (frame.addEventListener) {1741 frame.addEventListener("load", frameLoadHandler, false);1742 } else if (frame.attachEvent) {1743 frame.attachEvent("onload", frameLoadHandler);1744 }1745 frame.src = url;1746 transportLogic.foreverFrame.connections[frameId] = connection;1747 connection.frame = frame;1748 connection.frameId = frameId;1749 if (onSuccess) {1750 connection.onSuccess = function () {1751 connection.log("Iframe transport started.");1752 onSuccess();1753 };1754 }1755 },1756 reconnect: function (connection) {1757 var that = this;1758 // Need to verify connection state and verify before the setTimeout occurs because an application sleep could occur during the setTimeout duration.1759 if (transportLogic.isConnectedOrReconnecting(connection) && transportLogic.verifyLastActive(connection)) {1760 window.setTimeout(function () {1761 // Verify that we're ok to reconnect.1762 if (!transportLogic.verifyLastActive(connection)) {1763 return;1764 }1765 if (connection.frame && transportLogic.ensureReconnectingState(connection)) {1766 var frame = connection.frame,1767 src = transportLogic.getUrl(connection, that.name, true) + "&frameId=" + connection.frameId;1768 connection.log("Updating iframe src to '" + src + "'.");1769 frame.src = src;1770 }1771 }, connection.reconnectDelay);1772 }1773 },1774 lostConnection: function (connection) {1775 this.reconnect(connection);1776 },1777 send: function (connection, data) {1778 transportLogic.ajaxSend(connection, data);1779 },1780 receive: function (connection, data) {1781 var cw,1782 body,1783 response;1784 if (connection.json !== connection._originalJson) {1785 // If there's a custom JSON parser configured then serialize the object1786 // using the original (browser) JSON parser and then deserialize it using1787 // the custom parser (connection._parseResponse does that). This is so we1788 // can easily send the response from the server as "raw" JSON but still1789 // support custom JSON deserialization in the browser.1790 data = connection._originalJson.stringify(data);1791 }1792 response = connection._parseResponse(data);1793 transportLogic.processMessages(connection, response, connection.onSuccess);1794 // Protect against connection stopping from a callback trigger within the processMessages above.1795 if (connection.state === $.signalR.connectionState.connected) {1796 // Delete the script & div elements1797 connection.frameMessageCount = (connection.frameMessageCount || 0) + 1;1798 if (connection.frameMessageCount > signalR.transports.foreverFrame.iframeClearThreshold) {1799 connection.frameMessageCount = 0;1800 cw = connection.frame.contentWindow || connection.frame.contentDocument;1801 if (cw && cw.document && cw.document.body) {1802 body = cw.document.body;1803 // Remove all the child elements from the iframe's body to conserver memory1804 while (body.firstChild) {1805 body.removeChild(body.firstChild);1806 }1807 }1808 }1809 }1810 },1811 stop: function (connection) {1812 var cw = null;1813 // Stop attempting to prevent loading icon1814 loadPreventer.cancel();1815 if (connection.frame) {1816 if (connection.frame.stop) {1817 connection.frame.stop();1818 } else {1819 try {1820 cw = connection.frame.contentWindow || connection.frame.contentDocument;1821 if (cw.document && cw.document.execCommand) {1822 cw.document.execCommand("Stop");1823 }1824 }1825 catch (e) {1826 connection.log("Error occurred when stopping foreverFrame transport. Message = " + e.message + ".");1827 }1828 }1829 // Ensure the iframe is where we left it1830 if (connection.frame.parentNode === window.document.body) {1831 window.document.body.removeChild(connection.frame);1832 }1833 delete transportLogic.foreverFrame.connections[connection.frameId];1834 connection.frame = null;1835 connection.frameId = null;1836 delete connection.frame;1837 delete connection.frameId;1838 delete connection.onSuccess;1839 delete connection.frameMessageCount;1840 connection.log("Stopping forever frame.");1841 }1842 },1843 abort: function (connection, async) {1844 transportLogic.ajaxAbort(connection, async);1845 },1846 getConnection: function (id) {1847 return transportLogic.foreverFrame.connections[id];1848 },1849 started: function (connection) {1850 if (changeState(connection,1851 signalR.connectionState.reconnecting,1852 signalR.connectionState.connected) === true) {1853 $(connection).triggerHandler(events.onReconnect);1854 }1855 }1856 };1857}(window.jQuery, window));1858/* jquery.signalR.transports.longPolling.js */1859// Copyright (c) .NET Foundation. All rights reserved.1860// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.1861/*global window:false */1862/// <reference path="jquery.signalR.transports.common.js" />1863(function ($, window, undefined) {1864 var signalR = $.signalR,1865 events = $.signalR.events,1866 changeState = $.signalR.changeState,1867 isDisconnecting = $.signalR.isDisconnecting,1868 transportLogic = signalR.transports._logic;1869 signalR.transports.longPolling = {1870 name: "longPolling",1871 supportsKeepAlive: function () {1872 return false;1873 },1874 reconnectDelay: 3000,1875 start: function (connection, onSuccess, onFailed) {1876 /// <summary>Starts the long polling connection</summary>1877 /// <param name="connection" type="signalR">The SignalR connection to start</param>1878 var that = this,1879 fireConnect = function () {1880 fireConnect = $.noop;1881 connection.log("LongPolling connected.");1882 if (onSuccess) {1883 onSuccess();1884 } else {1885 connection.log("WARNING! The client received an init message after reconnecting.");1886 }1887 },1888 tryFailConnect = function (error) {1889 if (onFailed(error)) {1890 connection.log("LongPolling failed to connect.");1891 return true;1892 }1893 return false;1894 },1895 privateData = connection._,1896 reconnectErrors = 0,1897 fireReconnected = function (instance) {1898 window.clearTimeout(privateData.reconnectTimeoutId);1899 privateData.reconnectTimeoutId = null;1900 if (changeState(instance,1901 signalR.connectionState.reconnecting,1902 signalR.connectionState.connected) === true) {1903 // Successfully reconnected!1904 instance.log("Raising the reconnect event");1905 $(instance).triggerHandler(events.onReconnect);1906 }1907 },1908 // 1 hour1909 maxFireReconnectedTimeout = 3600000;1910 if (connection.pollXhr) {1911 connection.log("Polling xhr requests already exists, aborting.");1912 connection.stop();1913 }1914 connection.messageId = null;1915 privateData.reconnectTimeoutId = null;1916 privateData.pollTimeoutId = window.setTimeout(function () {1917 (function poll(instance, raiseReconnect) {1918 var messageId = instance.messageId,1919 connect = (messageId === null),1920 reconnecting = !connect,1921 polling = !raiseReconnect,1922 url = transportLogic.getUrl(instance, that.name, reconnecting, polling, true /* use Post for longPolling */),1923 postData = {};1924 if (instance.messageId) {1925 postData.messageId = instance.messageId;1926 }1927 if (instance.groupsToken) {1928 postData.groupsToken = instance.groupsToken;1929 }1930 // If we've disconnected during the time we've tried to re-instantiate the poll then stop.1931 if (isDisconnecting(instance) === true) {1932 return;1933 }1934 connection.log("Opening long polling request to '" + url + "'.");1935 instance.pollXhr = transportLogic.ajax(connection, {1936 xhrFields: {1937 onprogress: function () {1938 transportLogic.markLastMessage(connection);1939 }1940 },1941 url: url,1942 type: "POST",1943 contentType: signalR._.defaultContentType,1944 data: postData,1945 timeout: connection._.pollTimeout,1946 success: function (result) {1947 var minData,1948 delay = 0,1949 data,1950 shouldReconnect;1951 connection.log("Long poll complete.");1952 // Reset our reconnect errors so if we transition into a reconnecting state again we trigger1953 // reconnected quickly1954 reconnectErrors = 0;1955 try {1956 // Remove any keep-alives from the beginning of the result1957 minData = connection._parseResponse(result);1958 }1959 catch (error) {1960 transportLogic.handleParseFailure(instance, result, error, tryFailConnect, instance.pollXhr);1961 return;1962 }1963 // If there's currently a timeout to trigger reconnect, fire it now before processing messages1964 if (privateData.reconnectTimeoutId !== null) {1965 fireReconnected(instance);1966 }1967 if (minData) {1968 data = transportLogic.maximizePersistentResponse(minData);1969 }1970 transportLogic.processMessages(instance, minData, fireConnect);1971 if (data &&1972 $.type(data.LongPollDelay) === "number") {1973 delay = data.LongPollDelay;1974 }1975 if (isDisconnecting(instance) === true) {1976 return;1977 }1978 shouldReconnect = data && data.ShouldReconnect;1979 if (shouldReconnect) {1980 // Transition into the reconnecting state1981 // If this fails then that means that the user transitioned the connection into a invalid state in processMessages.1982 if (!transportLogic.ensureReconnectingState(instance)) {1983 return;1984 }1985 }1986 // We never want to pass a raiseReconnect flag after a successful poll. This is handled via the error function1987 if (delay > 0) {1988 privateData.pollTimeoutId = window.setTimeout(function () {1989 poll(instance, shouldReconnect);1990 }, delay);1991 } else {1992 poll(instance, shouldReconnect);1993 }1994 },1995 error: function (data, textStatus) {1996 var error = signalR._.transportError(signalR.resources.longPollFailed, connection.transport, data, instance.pollXhr);1997 // Stop trying to trigger reconnect, connection is in an error state1998 // If we're not in the reconnect state this will noop1999 window.clearTimeout(privateData.reconnectTimeoutId);2000 privateData.reconnectTimeoutId = null;2001 if (textStatus === "abort") {2002 connection.log("Aborted xhr request.");2003 return;2004 }2005 if (!tryFailConnect(error)) {2006 // Increment our reconnect errors, we assume all errors to be reconnect errors2007 // In the case that it's our first error this will cause Reconnect to be fired2008 // after 1 second due to reconnectErrors being = 1.2009 reconnectErrors++;2010 if (connection.state !== signalR.connectionState.reconnecting) {2011 connection.log("An error occurred using longPolling. Status = " + textStatus + ". Response = " + data.responseText + ".");2012 $(instance).triggerHandler(events.onError, [error]);2013 }2014 // We check the state here to verify that we're not in an invalid state prior to verifying Reconnect.2015 // If we're not in connected or reconnecting then the next ensureReconnectingState check will fail and will return.2016 // Therefore we don't want to change that failure code path.2017 if ((connection.state === signalR.connectionState.connected ||2018 connection.state === signalR.connectionState.reconnecting) &&2019 !transportLogic.verifyLastActive(connection)) {2020 return;2021 }2022 // Transition into the reconnecting state2023 // If this fails then that means that the user transitioned the connection into the disconnected or connecting state within the above error handler trigger.2024 if (!transportLogic.ensureReconnectingState(instance)) {2025 return;2026 }2027 // Call poll with the raiseReconnect flag as true after the reconnect delay2028 privateData.pollTimeoutId = window.setTimeout(function () {2029 poll(instance, true);2030 }, that.reconnectDelay);2031 }2032 }2033 });2034 // This will only ever pass after an error has occurred via the poll ajax procedure.2035 if (reconnecting && raiseReconnect === true) {2036 // We wait to reconnect depending on how many times we've failed to reconnect.2037 // This is essentially a heuristic that will exponentially increase in wait time before2038 // triggering reconnected. This depends on the "error" handler of Poll to cancel this2039 // timeout if it triggers before the Reconnected event fires.2040 // The Math.min at the end is to ensure that the reconnect timeout does not overflow.2041 privateData.reconnectTimeoutId = window.setTimeout(function () { fireReconnected(instance); }, Math.min(1000 * (Math.pow(2, reconnectErrors) - 1), maxFireReconnectedTimeout));2042 }2043 }(connection));2044 }, 250); // Have to delay initial poll so Chrome doesn't show loader spinner in tab2045 },2046 lostConnection: function (connection) {2047 if (connection.pollXhr) {2048 connection.pollXhr.abort("lostConnection");2049 }2050 },2051 send: function (connection, data) {2052 transportLogic.ajaxSend(connection, data);2053 },2054 stop: function (connection) {2055 /// <summary>Stops the long polling connection</summary>2056 /// <param name="connection" type="signalR">The SignalR connection to stop</param>2057 window.clearTimeout(connection._.pollTimeoutId);2058 window.clearTimeout(connection._.reconnectTimeoutId);2059 delete connection._.pollTimeoutId;2060 delete connection._.reconnectTimeoutId;2061 if (connection.pollXhr) {2062 connection.pollXhr.abort();2063 connection.pollXhr = null;2064 delete connection.pollXhr;2065 }2066 },2067 abort: function (connection, async) {2068 transportLogic.ajaxAbort(connection, async);2069 }2070 };2071}(window.jQuery, window));2072/* jquery.signalR.hubs.js */2073// Copyright (c) .NET Foundation. All rights reserved.2074// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.2075/*global window:false */2076/// <reference path="jquery.signalR.core.js" />2077(function ($, window, undefined) {2078 var eventNamespace = ".hubProxy",2079 signalR = $.signalR;2080 function makeEventName(event) {2081 return event + eventNamespace;2082 }2083 // Equivalent to Array.prototype.map2084 function map(arr, fun, thisp) {2085 var i,2086 length = arr.length,2087 result = [];2088 for (i = 0; i < length; i += 1) {2089 if (arr.hasOwnProperty(i)) {2090 result[i] = fun.call(thisp, arr[i], i, arr);2091 }2092 }2093 return result;2094 }2095 function getArgValue(a) {2096 return $.isFunction(a) ? null : ($.type(a) === "undefined" ? null : a);2097 }2098 function hasMembers(obj) {2099 for (var key in obj) {2100 // If we have any properties in our callback map then we have callbacks and can exit the loop via return2101 if (obj.hasOwnProperty(key)) {2102 return true;2103 }2104 }2105 return false;2106 }2107 function clearInvocationCallbacks(connection, error) {2108 /// <param name="connection" type="hubConnection" />2109 var callbacks = connection._.invocationCallbacks,2110 callback;2111 if (hasMembers(callbacks)) {2112 connection.log("Clearing hub invocation callbacks with error: " + error + ".");2113 }2114 // Reset the callback cache now as we have a local var referencing it2115 connection._.invocationCallbackId = 0;2116 delete connection._.invocationCallbacks;2117 connection._.invocationCallbacks = {};2118 // Loop over the callbacks and invoke them.2119 // We do this using a local var reference and *after* we've cleared the cache2120 // so that if a fail callback itself tries to invoke another method we don't2121 // end up with its callback in the list we're looping over.2122 for (var callbackId in callbacks) {2123 callback = callbacks[callbackId];2124 callback.method.call(callback.scope, { E: error });2125 }2126 }2127 // hubProxy2128 function hubProxy(hubConnection, hubName) {2129 /// <summary>2130 /// Creates a new proxy object for the given hub connection that can be used to invoke2131 /// methods on server hubs and handle client method invocation requests from the server.2132 /// </summary>2133 return new hubProxy.fn.init(hubConnection, hubName);2134 }2135 hubProxy.fn = hubProxy.prototype = {2136 init: function (connection, hubName) {2137 this.state = {};2138 this.connection = connection;2139 this.hubName = hubName;2140 this._ = {2141 callbackMap: {}2142 };2143 },2144 constructor: hubProxy,2145 hasSubscriptions: function () {2146 return hasMembers(this._.callbackMap);2147 },2148 on: function (eventName, callback) {2149 /// <summary>Wires up a callback to be invoked when a invocation request is received from the server hub.</summary>2150 /// <param name="eventName" type="String">The name of the hub event to register the callback for.</param>2151 /// <param name="callback" type="Function">The callback to be invoked.</param>2152 var that = this,2153 callbackMap = that._.callbackMap;2154 // Normalize the event name to lowercase2155 eventName = eventName.toLowerCase();2156 // If there is not an event registered for this callback yet we want to create its event space in the callback map.2157 if (!callbackMap[eventName]) {2158 callbackMap[eventName] = {};2159 }2160 // Map the callback to our encompassed function2161 callbackMap[eventName][callback] = function (e, data) {2162 callback.apply(that, data);2163 };2164 $(that).bind(makeEventName(eventName), callbackMap[eventName][callback]);2165 return that;2166 },2167 off: function (eventName, callback) {2168 /// <summary>Removes the callback invocation request from the server hub for the given event name.</summary>2169 /// <param name="eventName" type="String">The name of the hub event to unregister the callback for.</param>2170 /// <param name="callback" type="Function">The callback to be invoked.</param>2171 var that = this,2172 callbackMap = that._.callbackMap,2173 callbackSpace;2174 // Normalize the event name to lowercase2175 eventName = eventName.toLowerCase();2176 callbackSpace = callbackMap[eventName];2177 // Verify that there is an event space to unbind2178 if (callbackSpace) {2179 // Only unbind if there's an event bound with eventName and a callback with the specified callback2180 if (callbackSpace[callback]) {2181 $(that).unbind(makeEventName(eventName), callbackSpace[callback]);2182 // Remove the callback from the callback map2183 delete callbackSpace[callback];2184 // Check if there are any members left on the event, if not we need to destroy it.2185 if (!hasMembers(callbackSpace)) {2186 delete callbackMap[eventName];2187 }2188 } else if (!callback) { // Check if we're removing the whole event and we didn't error because of an invalid callback2189 $(that).unbind(makeEventName(eventName));2190 delete callbackMap[eventName];2191 }2192 }2193 return that;2194 },2195 invoke: function (methodName) {2196 /// <summary>Invokes a server hub method with the given arguments.</summary>2197 /// <param name="methodName" type="String">The name of the server hub method.</param>2198 var that = this,2199 connection = that.connection,2200 args = $.makeArray(arguments).slice(1),2201 argValues = map(args, getArgValue),2202 data = { H: that.hubName, M: methodName, A: argValues, I: connection._.invocationCallbackId },2203 d = $.Deferred(),2204 callback = function (minResult) {2205 var result = that._maximizeHubResponse(minResult),2206 source,2207 error;2208 // Update the hub state2209 $.extend(that.state, result.State);2210 if (result.Progress) {2211 if (d.notifyWith) {2212 // Progress is only supported in jQuery 1.7+2213 d.notifyWith(that, [result.Progress.Data]);2214 } else if(!connection._.progressjQueryVersionLogged) {2215 connection.log("A hub method invocation progress update was received but the version of jQuery in use (" + $.prototype.jquery + ") does not support progress updates. Upgrade to jQuery 1.7+ to receive progress notifications.");2216 connection._.progressjQueryVersionLogged = true;2217 }2218 } else if (result.Error) {2219 // Server hub method threw an exception, log it & reject the deferred2220 if (result.StackTrace) {2221 connection.log(result.Error + "\n" + result.StackTrace + ".");2222 }2223 // result.ErrorData is only set if a HubException was thrown2224 source = result.IsHubException ? "HubException" : "Exception";2225 error = signalR._.error(result.Error, source);2226 error.data = result.ErrorData;2227 connection.log(that.hubName + "." + methodName + " failed to execute. Error: " + error.message);2228 d.rejectWith(that, [error]);2229 } else {2230 // Server invocation succeeded, resolve the deferred2231 connection.log("Invoked " + that.hubName + "." + methodName);2232 d.resolveWith(that, [result.Result]);2233 }2234 };2235 connection._.invocationCallbacks[connection._.invocationCallbackId.toString()] = { scope: that, method: callback };2236 connection._.invocationCallbackId += 1;2237 if (!$.isEmptyObject(that.state)) {2238 data.S = that.state;2239 }2240 connection.log("Invoking " + that.hubName + "." + methodName);2241 connection.send(data);2242 return d.promise();2243 },2244 _maximizeHubResponse: function (minHubResponse) {2245 return {2246 State: minHubResponse.S,2247 Result: minHubResponse.R,2248 Progress: minHubResponse.P ? {2249 Id: minHubResponse.P.I,2250 Data: minHubResponse.P.D2251 } : null,2252 Id: minHubResponse.I,2253 IsHubException: minHubResponse.H,2254 Error: minHubResponse.E,2255 StackTrace: minHubResponse.T,2256 ErrorData: minHubResponse.D2257 };2258 }2259 };2260 hubProxy.fn.init.prototype = hubProxy.fn;2261 // hubConnection2262 function hubConnection(url, options) {2263 /// <summary>Creates a new hub connection.</summary>2264 /// <param name="url" type="String">[Optional] The hub route url, defaults to "/signalr".</param>2265 /// <param name="options" type="Object">[Optional] Settings to use when creating the hubConnection.</param>2266 var settings = {2267 qs: null,2268 logging: false,2269 useDefaultPath: true2270 };2271 $.extend(settings, options);2272 if (!url || settings.useDefaultPath) {2273 url = (url || "") + "/signalr";2274 }2275 return new hubConnection.fn.init(url, settings);2276 }...
jquery.signalR-2.2.0.js
Source:jquery.signalR-2.2.0.js
...826 // Check if the keep alive has completely timed out827 if (timeElapsed >= keepAliveData.timeout) {828 connection.log("Keep alive timed out. Notifying transport that connection has been lost.");829 // Notify transport that the connection has been lost830 connection.transport.lostConnection(connection);831 } else if (timeElapsed >= keepAliveData.timeoutWarning) {832 // This is to assure that the user only gets a single warning833 if (!keepAliveData.userNotified) {834 connection.log("Keep alive has been missed, connection may be dead/slow.");835 $(connection).triggerHandler(events.onConnectionSlow);836 keepAliveData.userNotified = true;837 }838 } else {839 keepAliveData.userNotified = false;840 }841 }842 }843 function getAjaxUrl(connection, path) {844 var url = connection.url + path;845 if (connection.transport) {846 url += "?transport=" + connection.transport.name;847 }848 return transportLogic.prepareQueryString(connection, url);849 }850 function InitHandler(connection) {851 this.connection = connection;852 this.startRequested = false;853 this.startCompleted = false;854 this.connectionStopped = false;855 }856 InitHandler.prototype = {857 start: function (transport, onSuccess, onFallback) {858 var that = this,859 connection = that.connection,860 failCalled = false;861 if (that.startRequested || that.connectionStopped) {862 connection.log("WARNING! " + transport.name + " transport cannot be started. Initialization ongoing or completed.");863 return;864 }865 connection.log(transport.name + " transport starting.");866 that.transportTimeoutHandle = window.setTimeout(function () {867 if (!failCalled) {868 failCalled = true;869 connection.log(transport.name + " transport timed out when trying to connect.");870 that.transportFailed(transport, undefined, onFallback);871 }872 }, connection._.totalTransportConnectTimeout);873 transport.start(connection, function () {874 if (!failCalled) {875 that.initReceived(transport, onSuccess);876 }877 }, function (error) {878 // Don't allow the same transport to cause onFallback to be called twice879 if (!failCalled) {880 failCalled = true;881 that.transportFailed(transport, error, onFallback);882 }883 // Returns true if the transport should stop;884 // false if it should attempt to reconnect885 return !that.startCompleted || that.connectionStopped;886 });887 },888 stop: function () {889 this.connectionStopped = true;890 window.clearTimeout(this.transportTimeoutHandle);891 signalR.transports._logic.tryAbortStartRequest(this.connection);892 },893 initReceived: function (transport, onSuccess) {894 var that = this,895 connection = that.connection;896 if (that.startRequested) {897 connection.log("WARNING! The client received multiple init messages.");898 return;899 }900 if (that.connectionStopped) {901 return;902 }903 that.startRequested = true;904 window.clearTimeout(that.transportTimeoutHandle);905 connection.log(transport.name + " transport connected. Initiating start request.");906 signalR.transports._logic.ajaxStart(connection, function () {907 that.startCompleted = true;908 onSuccess();909 });910 },911 transportFailed: function (transport, error, onFallback) {912 var connection = this.connection,913 deferred = connection._deferral,914 wrappedError;915 if (this.connectionStopped) {916 return;917 }918 window.clearTimeout(this.transportTimeoutHandle);919 if (!this.startRequested) {920 transport.stop(connection);921 connection.log(transport.name + " transport failed to connect. Attempting to fall back.");922 onFallback();923 } else if (!this.startCompleted) {924 // Do not attempt to fall back if a start request is ongoing during a transport failure.925 // Instead, trigger an error and stop the connection.926 wrappedError = signalR._.error(signalR.resources.errorDuringStartRequest, error);927 connection.log(transport.name + " transport failed during the start request. Stopping the connection.");928 $(connection).triggerHandler(events.onError, [wrappedError]);929 if (deferred) {930 deferred.reject(wrappedError);931 }932 connection.stop();933 } else {934 // The start request has completed, but the connection has not stopped.935 // No need to do anything here. The transport should attempt its normal reconnect logic.936 }937 }938 };939 transportLogic = signalR.transports._logic = {940 ajax: function (connection, options) {941 return $.ajax(942 $.extend(/*deep copy*/ true, {}, $.signalR.ajaxDefaults, {943 type: "GET",944 data: {},945 xhrFields: { withCredentials: connection.withCredentials },946 contentType: connection.contentType,947 dataType: connection.ajaxDataType948 }, options));949 },950 pingServer: function (connection) {951 /// <summary>Pings the server</summary>952 /// <param name="connection" type="signalr">Connection associated with the server ping</param>953 /// <returns type="signalR" />954 var url,955 xhr,956 deferral = $.Deferred();957 if (connection.transport) {958 url = connection.url + "/ping";959 url = transportLogic.addQs(url, connection.qs);960 xhr = transportLogic.ajax(connection, {961 url: url,962 success: function (result) {963 var data;964 try {965 data = connection._parseResponse(result);966 }967 catch (error) {968 deferral.reject(969 signalR._.transportError(970 signalR.resources.pingServerFailedParse,971 connection.transport,972 error,973 xhr974 )975 );976 connection.stop();977 return;978 }979 if (data.Response === "pong") {980 deferral.resolve();981 }982 else {983 deferral.reject(984 signalR._.transportError(985 signalR._.format(signalR.resources.pingServerFailedInvalidResponse, result),986 connection.transport,987 null /* error */,988 xhr989 )990 );991 }992 },993 error: function (error) {994 if (error.status === 401 || error.status === 403) {995 deferral.reject(996 signalR._.transportError(997 signalR._.format(signalR.resources.pingServerFailedStatusCode, error.status),998 connection.transport,999 error,1000 xhr1001 )1002 );1003 connection.stop();1004 }1005 else {1006 deferral.reject(1007 signalR._.transportError(1008 signalR.resources.pingServerFailed,1009 connection.transport,1010 error,1011 xhr1012 )1013 );1014 }1015 }1016 });1017 }1018 else {1019 deferral.reject(1020 signalR._.transportError(1021 signalR.resources.noConnectionTransport,1022 connection.transport1023 )1024 );1025 }1026 return deferral.promise();1027 },1028 prepareQueryString: function (connection, url) {1029 var preparedUrl;1030 // Use addQs to start since it handles the ?/& prefix for us1031 preparedUrl = transportLogic.addQs(url, "clientProtocol=" + connection.clientProtocol);1032 // Add the user-specified query string params if any1033 preparedUrl = transportLogic.addQs(preparedUrl, connection.qs);1034 if (connection.token) {1035 preparedUrl += "&connectionToken=" + window.encodeURIComponent(connection.token);1036 }1037 if (connection.data) {1038 preparedUrl += "&connectionData=" + window.encodeURIComponent(connection.data);1039 }1040 return preparedUrl;1041 },1042 addQs: function (url, qs) {1043 var appender = url.indexOf("?") !== -1 ? "&" : "?",1044 firstChar;1045 if (!qs) {1046 return url;1047 }1048 if (typeof (qs) === "object") {1049 return url + appender + $.param(qs);1050 }1051 if (typeof (qs) === "string") {1052 firstChar = qs.charAt(0);1053 if (firstChar === "?" || firstChar === "&") {1054 appender = "";1055 }1056 return url + appender + qs;1057 }1058 throw new Error("Query string property must be either a string or object.");1059 },1060 // BUG #2953: The url needs to be same otherwise it will cause a memory leak1061 getUrl: function (connection, transport, reconnecting, poll, ajaxPost) {1062 /// <summary>Gets the url for making a GET based connect request</summary>1063 var baseUrl = transport === "webSockets" ? "" : connection.baseUrl,1064 url = baseUrl + connection.appRelativeUrl,1065 qs = "transport=" + transport;1066 if (!ajaxPost && connection.groupsToken) {1067 qs += "&groupsToken=" + window.encodeURIComponent(connection.groupsToken);1068 }1069 if (!reconnecting) {1070 url += "/connect";1071 } else {1072 if (poll) {1073 // longPolling transport specific1074 url += "/poll";1075 } else {1076 url += "/reconnect";1077 }1078 if (!ajaxPost && connection.messageId) {1079 qs += "&messageId=" + window.encodeURIComponent(connection.messageId);1080 }1081 }1082 url += "?" + qs;1083 url = transportLogic.prepareQueryString(connection, url);1084 if (!ajaxPost) {1085 url += "&tid=" + Math.floor(Math.random() * 11);1086 }1087 return url;1088 },1089 maximizePersistentResponse: function (minPersistentResponse) {1090 return {1091 MessageId: minPersistentResponse.C,1092 Messages: minPersistentResponse.M,1093 Initialized: typeof (minPersistentResponse.S) !== "undefined" ? true : false,1094 ShouldReconnect: typeof (minPersistentResponse.T) !== "undefined" ? true : false,1095 LongPollDelay: minPersistentResponse.L,1096 GroupsToken: minPersistentResponse.G1097 };1098 },1099 updateGroups: function (connection, groupsToken) {1100 if (groupsToken) {1101 connection.groupsToken = groupsToken;1102 }1103 },1104 stringifySend: function (connection, message) {1105 if (typeof (message) === "string" || typeof (message) === "undefined" || message === null) {1106 return message;1107 }1108 return connection.json.stringify(message);1109 },1110 ajaxSend: function (connection, data) {1111 var payload = transportLogic.stringifySend(connection, data),1112 url = getAjaxUrl(connection, "/send"),1113 xhr,1114 onFail = function (error, connection) {1115 $(connection).triggerHandler(events.onError, [signalR._.transportError(signalR.resources.sendFailed, connection.transport, error, xhr), data]);1116 };1117 xhr = transportLogic.ajax(connection, {1118 url: url,1119 type: connection.ajaxDataType === "jsonp" ? "GET" : "POST",1120 contentType: signalR._.defaultContentType,1121 data: {1122 data: payload1123 },1124 success: function (result) {1125 var res;1126 if (result) {1127 try {1128 res = connection._parseResponse(result);1129 }1130 catch (error) {1131 onFail(error, connection);1132 connection.stop();1133 return;1134 }1135 transportLogic.triggerReceived(connection, res);1136 }1137 },1138 error: function (error, textStatus) {1139 if (textStatus === "abort" || textStatus === "parsererror") {1140 // The parsererror happens for sends that don't return any data, and hence1141 // don't write the jsonp callback to the response. This is harder to fix on the server1142 // so just hack around it on the client for now.1143 return;1144 }1145 onFail(error, connection);1146 }1147 });1148 return xhr;1149 },1150 ajaxAbort: function (connection, async) {1151 if (typeof (connection.transport) === "undefined") {1152 return;1153 }1154 // Async by default unless explicitly overidden1155 async = typeof async === "undefined" ? true : async;1156 var url = getAjaxUrl(connection, "/abort");1157 transportLogic.ajax(connection, {1158 url: url,1159 async: async,1160 timeout: 1000,1161 type: "POST"1162 });1163 connection.log("Fired ajax abort async = " + async + ".");1164 },1165 ajaxStart: function (connection, onSuccess) {1166 var rejectDeferred = function (error) {1167 var deferred = connection._deferral;1168 if (deferred) {1169 deferred.reject(error);1170 }1171 },1172 triggerStartError = function (error) {1173 connection.log("The start request failed. Stopping the connection.");1174 $(connection).triggerHandler(events.onError, [error]);1175 rejectDeferred(error);1176 connection.stop();1177 };1178 connection._.startRequest = transportLogic.ajax(connection, {1179 url: getAjaxUrl(connection, "/start"),1180 success: function (result, statusText, xhr) {1181 var data;1182 try {1183 data = connection._parseResponse(result);1184 } catch (error) {1185 triggerStartError(signalR._.error(1186 signalR._.format(signalR.resources.errorParsingStartResponse, result),1187 error, xhr));1188 return;1189 }1190 if (data.Response === "started") {1191 onSuccess();1192 } else {1193 triggerStartError(signalR._.error(1194 signalR._.format(signalR.resources.invalidStartResponse, result),1195 null /* error */, xhr));1196 }1197 },1198 error: function (xhr, statusText, error) {1199 if (statusText !== startAbortText) {1200 triggerStartError(signalR._.error(1201 signalR.resources.errorDuringStartRequest,1202 error, xhr));1203 } else {1204 // Stop has been called, no need to trigger the error handler1205 // or stop the connection again with onStartError1206 connection.log("The start request aborted because connection.stop() was called.");1207 rejectDeferred(signalR._.error(1208 signalR.resources.stoppedDuringStartRequest,1209 null /* error */, xhr));1210 }1211 }1212 });1213 },1214 tryAbortStartRequest: function (connection) {1215 if (connection._.startRequest) {1216 // If the start request has already completed this will noop.1217 connection._.startRequest.abort(startAbortText);1218 delete connection._.startRequest;1219 }1220 },1221 tryInitialize: function (persistentResponse, onInitialized) {1222 if (persistentResponse.Initialized) {1223 onInitialized();1224 }1225 },1226 triggerReceived: function (connection, data) {1227 if (!connection._.connectingMessageBuffer.tryBuffer(data)) {1228 $(connection).triggerHandler(events.onReceived, [data]);1229 }1230 },1231 processMessages: function (connection, minData, onInitialized) {1232 var data;1233 // Update the last message time stamp1234 transportLogic.markLastMessage(connection);1235 if (minData) {1236 data = transportLogic.maximizePersistentResponse(minData);1237 transportLogic.updateGroups(connection, data.GroupsToken);1238 if (data.MessageId) {1239 connection.messageId = data.MessageId;1240 }1241 if (data.Messages) {1242 $.each(data.Messages, function (index, message) {1243 transportLogic.triggerReceived(connection, message);1244 });1245 transportLogic.tryInitialize(data, onInitialized);1246 }1247 }1248 },1249 monitorKeepAlive: function (connection) {1250 var keepAliveData = connection._.keepAliveData;1251 // If we haven't initiated the keep alive timeouts then we need to1252 if (!keepAliveData.monitoring) {1253 keepAliveData.monitoring = true;1254 transportLogic.markLastMessage(connection);1255 // Save the function so we can unbind it on stop1256 connection._.keepAliveData.reconnectKeepAliveUpdate = function () {1257 // Mark a new message so that keep alive doesn't time out connections1258 transportLogic.markLastMessage(connection);1259 };1260 // Update Keep alive on reconnect1261 $(connection).bind(events.onReconnect, connection._.keepAliveData.reconnectKeepAliveUpdate);1262 connection.log("Now monitoring keep alive with a warning timeout of " + keepAliveData.timeoutWarning + ", keep alive timeout of " + keepAliveData.timeout + " and disconnecting timeout of " + connection.disconnectTimeout);1263 } else {1264 connection.log("Tried to monitor keep alive but it's already being monitored.");1265 }1266 },1267 stopMonitoringKeepAlive: function (connection) {1268 var keepAliveData = connection._.keepAliveData;1269 // Only attempt to stop the keep alive monitoring if its being monitored1270 if (keepAliveData.monitoring) {1271 // Stop monitoring1272 keepAliveData.monitoring = false;1273 // Remove the updateKeepAlive function from the reconnect event1274 $(connection).unbind(events.onReconnect, connection._.keepAliveData.reconnectKeepAliveUpdate);1275 // Clear all the keep alive data1276 connection._.keepAliveData = {};1277 connection.log("Stopping the monitoring of the keep alive.");1278 }1279 },1280 startHeartbeat: function (connection) {1281 connection._.lastActiveAt = new Date().getTime();1282 beat(connection);1283 },1284 markLastMessage: function (connection) {1285 connection._.lastMessageAt = new Date().getTime();1286 },1287 markActive: function (connection) {1288 if (transportLogic.verifyLastActive(connection)) {1289 connection._.lastActiveAt = new Date().getTime();1290 return true;1291 }1292 return false;1293 },1294 isConnectedOrReconnecting: function (connection) {1295 return connection.state === signalR.connectionState.connected ||1296 connection.state === signalR.connectionState.reconnecting;1297 },1298 ensureReconnectingState: function (connection) {1299 if (changeState(connection,1300 signalR.connectionState.connected,1301 signalR.connectionState.reconnecting) === true) {1302 $(connection).triggerHandler(events.onReconnecting);1303 }1304 return connection.state === signalR.connectionState.reconnecting;1305 },1306 clearReconnectTimeout: function (connection) {1307 if (connection && connection._.reconnectTimeout) {1308 window.clearTimeout(connection._.reconnectTimeout);1309 delete connection._.reconnectTimeout;1310 }1311 },1312 verifyLastActive: function (connection) {1313 if (new Date().getTime() - connection._.lastActiveAt >= connection.reconnectWindow) {1314 var message = signalR._.format(signalR.resources.reconnectWindowTimeout, new Date(connection._.lastActiveAt), connection.reconnectWindow);1315 connection.log(message);1316 $(connection).triggerHandler(events.onError, [signalR._.error(message, /* source */ "TimeoutException")]);1317 connection.stop(/* async */ false, /* notifyServer */ false);1318 return false;1319 }1320 return true;1321 },1322 reconnect: function (connection, transportName) {1323 var transport = signalR.transports[transportName];1324 // We should only set a reconnectTimeout if we are currently connected1325 // and a reconnectTimeout isn't already set.1326 if (transportLogic.isConnectedOrReconnecting(connection) && !connection._.reconnectTimeout) {1327 // Need to verify before the setTimeout occurs because an application sleep could occur during the setTimeout duration.1328 if (!transportLogic.verifyLastActive(connection)) {1329 return;1330 }1331 connection._.reconnectTimeout = window.setTimeout(function () {1332 if (!transportLogic.verifyLastActive(connection)) {1333 return;1334 }1335 transport.stop(connection);1336 if (transportLogic.ensureReconnectingState(connection)) {1337 connection.log(transportName + " reconnecting.");1338 transport.start(connection);1339 }1340 }, connection.reconnectDelay);1341 }1342 },1343 handleParseFailure: function (connection, result, error, onFailed, context) {1344 var wrappedError = signalR._.transportError(1345 signalR._.format(signalR.resources.parseFailed, result),1346 connection.transport,1347 error,1348 context);1349 // If we're in the initialization phase trigger onFailed, otherwise stop the connection.1350 if (onFailed && onFailed(wrappedError)) {1351 connection.log("Failed to parse server response while attempting to connect.");1352 } else {1353 $(connection).triggerHandler(events.onError, [wrappedError]);1354 connection.stop();1355 }1356 },1357 initHandler: function (connection) {1358 return new InitHandler(connection);1359 },1360 foreverFrame: {1361 count: 0,1362 connections: {}1363 }1364 };1365}(window.jQuery, window));1366/* jquery.signalR.transports.webSockets.js */1367// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.md in the project root for license information.1368/*global window:false */1369/// <reference path="jquery.signalR.transports.common.js" />1370(function ($, window, undefined) {1371 var signalR = $.signalR,1372 events = $.signalR.events,1373 changeState = $.signalR.changeState,1374 transportLogic = signalR.transports._logic;1375 signalR.transports.webSockets = {1376 name: "webSockets",1377 supportsKeepAlive: function () {1378 return true;1379 },1380 send: function (connection, data) {1381 var payload = transportLogic.stringifySend(connection, data);1382 try {1383 connection.socket.send(payload);1384 } catch (ex) {1385 $(connection).triggerHandler(events.onError,1386 [signalR._.transportError(1387 signalR.resources.webSocketsInvalidState,1388 connection.transport,1389 ex,1390 connection.socket1391 ),1392 data]);1393 }1394 },1395 start: function (connection, onSuccess, onFailed) {1396 var url,1397 opened = false,1398 that = this,1399 reconnecting = !onSuccess,1400 $connection = $(connection);1401 if (!window.WebSocket) {1402 onFailed();1403 return;1404 }1405 if (!connection.socket) {1406 if (connection.webSocketServerUrl) {1407 url = connection.webSocketServerUrl;1408 } else {1409 url = connection.wsProtocol + connection.host;1410 }1411 url += transportLogic.getUrl(connection, this.name, reconnecting);1412 connection.log("Connecting to websocket endpoint '" + url + "'.");1413 connection.socket = new window.WebSocket(url);1414 connection.socket.onopen = function () {1415 opened = true;1416 connection.log("Websocket opened.");1417 transportLogic.clearReconnectTimeout(connection);1418 if (changeState(connection,1419 signalR.connectionState.reconnecting,1420 signalR.connectionState.connected) === true) {1421 $connection.triggerHandler(events.onReconnect);1422 }1423 };1424 connection.socket.onclose = function (event) {1425 var error;1426 // Only handle a socket close if the close is from the current socket.1427 // Sometimes on disconnect the server will push down an onclose event1428 // to an expired socket.1429 if (this === connection.socket) {1430 if (opened && typeof event.wasClean !== "undefined" && event.wasClean === false) {1431 // Ideally this would use the websocket.onerror handler (rather than checking wasClean in onclose) but1432 // I found in some circumstances Chrome won't call onerror. This implementation seems to work on all browsers.1433 error = signalR._.transportError(1434 signalR.resources.webSocketClosed,1435 connection.transport,1436 event);1437 connection.log("Unclean disconnect from websocket: " + (event.reason || "[no reason given]."));1438 } else {1439 connection.log("Websocket closed.");1440 }1441 if (!onFailed || !onFailed(error)) {1442 if (error) {1443 $(connection).triggerHandler(events.onError, [error]);1444 }1445 that.reconnect(connection);1446 }1447 }1448 };1449 connection.socket.onmessage = function (event) {1450 var data;1451 try {1452 data = connection._parseResponse(event.data);1453 }1454 catch (error) {1455 transportLogic.handleParseFailure(connection, event.data, error, onFailed, event);1456 return;1457 }1458 if (data) {1459 // data.M is PersistentResponse.Messages1460 if ($.isEmptyObject(data) || data.M) {1461 transportLogic.processMessages(connection, data, onSuccess);1462 } else {1463 // For websockets we need to trigger onReceived1464 // for callbacks to outgoing hub calls.1465 transportLogic.triggerReceived(connection, data);1466 }1467 }1468 };1469 }1470 },1471 reconnect: function (connection) {1472 transportLogic.reconnect(connection, this.name);1473 },1474 lostConnection: function (connection) {1475 this.reconnect(connection);1476 },1477 stop: function (connection) {1478 // Don't trigger a reconnect after stopping1479 transportLogic.clearReconnectTimeout(connection);1480 if (connection.socket) {1481 connection.log("Closing the Websocket.");1482 connection.socket.close();1483 connection.socket = null;1484 }1485 },1486 abort: function (connection, async) {1487 transportLogic.ajaxAbort(connection, async);1488 }1489 };1490}(window.jQuery, window));1491/* jquery.signalR.transports.serverSentEvents.js */1492// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.md in the project root for license information.1493/*global window:false */1494/// <reference path="jquery.signalR.transports.common.js" />1495(function ($, window, undefined) {1496 var signalR = $.signalR,1497 events = $.signalR.events,1498 changeState = $.signalR.changeState,1499 transportLogic = signalR.transports._logic,1500 clearReconnectAttemptTimeout = function (connection) {1501 window.clearTimeout(connection._.reconnectAttemptTimeoutHandle);1502 delete connection._.reconnectAttemptTimeoutHandle;1503 };1504 signalR.transports.serverSentEvents = {1505 name: "serverSentEvents",1506 supportsKeepAlive: function () {1507 return true;1508 },1509 timeOut: 3000,1510 start: function (connection, onSuccess, onFailed) {1511 var that = this,1512 opened = false,1513 $connection = $(connection),1514 reconnecting = !onSuccess,1515 url;1516 if (connection.eventSource) {1517 connection.log("The connection already has an event source. Stopping it.");1518 connection.stop();1519 }1520 if (!window.EventSource) {1521 if (onFailed) {1522 connection.log("This browser doesn't support SSE.");1523 onFailed();1524 }1525 return;1526 }1527 url = transportLogic.getUrl(connection, this.name, reconnecting);1528 try {1529 connection.log("Attempting to connect to SSE endpoint '" + url + "'.");1530 connection.eventSource = new window.EventSource(url, { withCredentials: connection.withCredentials });1531 }1532 catch (e) {1533 connection.log("EventSource failed trying to connect with error " + e.Message + ".");1534 if (onFailed) {1535 // The connection failed, call the failed callback1536 onFailed();1537 } else {1538 $connection.triggerHandler(events.onError, [signalR._.transportError(signalR.resources.eventSourceFailedToConnect, connection.transport, e)]);1539 if (reconnecting) {1540 // If we were reconnecting, rather than doing initial connect, then try reconnect again1541 that.reconnect(connection);1542 }1543 }1544 return;1545 }1546 if (reconnecting) {1547 connection._.reconnectAttemptTimeoutHandle = window.setTimeout(function () {1548 if (opened === false) {1549 // If we're reconnecting and the event source is attempting to connect,1550 // don't keep retrying. This causes duplicate connections to spawn.1551 if (connection.eventSource.readyState !== window.EventSource.OPEN) {1552 // If we were reconnecting, rather than doing initial connect, then try reconnect again1553 that.reconnect(connection);1554 }1555 }1556 },1557 that.timeOut);1558 }1559 connection.eventSource.addEventListener("open", function (e) {1560 connection.log("EventSource connected.");1561 clearReconnectAttemptTimeout(connection);1562 transportLogic.clearReconnectTimeout(connection);1563 if (opened === false) {1564 opened = true;1565 if (changeState(connection,1566 signalR.connectionState.reconnecting,1567 signalR.connectionState.connected) === true) {1568 $connection.triggerHandler(events.onReconnect);1569 }1570 }1571 }, false);1572 connection.eventSource.addEventListener("message", function (e) {1573 var res;1574 // process messages1575 if (e.data === "initialized") {1576 return;1577 }1578 try {1579 res = connection._parseResponse(e.data);1580 }1581 catch (error) {1582 transportLogic.handleParseFailure(connection, e.data, error, onFailed, e);1583 return;1584 }1585 transportLogic.processMessages(connection, res, onSuccess);1586 }, false);1587 connection.eventSource.addEventListener("error", function (e) {1588 var error = signalR._.transportError(1589 signalR.resources.eventSourceError,1590 connection.transport,1591 e);1592 // Only handle an error if the error is from the current Event Source.1593 // Sometimes on disconnect the server will push down an error event1594 // to an expired Event Source.1595 if (this !== connection.eventSource) {1596 return;1597 }1598 if (onFailed && onFailed(error)) {1599 return;1600 }1601 connection.log("EventSource readyState: " + connection.eventSource.readyState + ".");1602 if (e.eventPhase === window.EventSource.CLOSED) {1603 // We don't use the EventSource's native reconnect function as it1604 // doesn't allow us to change the URL when reconnecting. We need1605 // to change the URL to not include the /connect suffix, and pass1606 // the last message id we received.1607 connection.log("EventSource reconnecting due to the server connection ending.");1608 that.reconnect(connection);1609 } else {1610 // connection error1611 connection.log("EventSource error.");1612 $connection.triggerHandler(events.onError, [error]);1613 }1614 }, false);1615 },1616 reconnect: function (connection) {1617 transportLogic.reconnect(connection, this.name);1618 },1619 lostConnection: function (connection) {1620 this.reconnect(connection);1621 },1622 send: function (connection, data) {1623 transportLogic.ajaxSend(connection, data);1624 },1625 stop: function (connection) {1626 // Don't trigger a reconnect after stopping1627 clearReconnectAttemptTimeout(connection);1628 transportLogic.clearReconnectTimeout(connection);1629 if (connection && connection.eventSource) {1630 connection.log("EventSource calling close().");1631 connection.eventSource.close();1632 connection.eventSource = null;1633 delete connection.eventSource;1634 }1635 },1636 abort: function (connection, async) {1637 transportLogic.ajaxAbort(connection, async);1638 }1639 };1640}(window.jQuery, window));1641/* jquery.signalR.transports.foreverFrame.js */1642// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.md in the project root for license information.1643/*global window:false */1644/// <reference path="jquery.signalR.transports.common.js" />1645(function ($, window, undefined) {1646 var signalR = $.signalR,1647 events = $.signalR.events,1648 changeState = $.signalR.changeState,1649 transportLogic = signalR.transports._logic,1650 createFrame = function () {1651 var frame = window.document.createElement("iframe");1652 frame.setAttribute("style", "position:absolute;top:0;left:0;width:0;height:0;visibility:hidden;");1653 return frame;1654 },1655 // Used to prevent infinite loading icon spins in older versions of ie1656 // We build this object inside a closure so we don't pollute the rest of 1657 // the foreverFrame transport with unnecessary functions/utilities.1658 loadPreventer = (function () {1659 var loadingFixIntervalId = null,1660 loadingFixInterval = 1000,1661 attachedTo = 0;1662 return {1663 prevent: function () {1664 // Prevent additional iframe removal procedures from newer browsers1665 if (signalR._.ieVersion <= 8) {1666 // We only ever want to set the interval one time, so on the first attachedTo1667 if (attachedTo === 0) {1668 // Create and destroy iframe every 3 seconds to prevent loading icon, super hacky1669 loadingFixIntervalId = window.setInterval(function () {1670 var tempFrame = createFrame();1671 window.document.body.appendChild(tempFrame);1672 window.document.body.removeChild(tempFrame);1673 tempFrame = null;1674 }, loadingFixInterval);1675 }1676 attachedTo++;1677 }1678 },1679 cancel: function () {1680 // Only clear the interval if there's only one more object that the loadPreventer is attachedTo1681 if (attachedTo === 1) {1682 window.clearInterval(loadingFixIntervalId);1683 }1684 if (attachedTo > 0) {1685 attachedTo--;1686 }1687 }1688 };1689 })();1690 signalR.transports.foreverFrame = {1691 name: "foreverFrame",1692 supportsKeepAlive: function () {1693 return true;1694 },1695 // Added as a value here so we can create tests to verify functionality1696 iframeClearThreshold: 50,1697 start: function (connection, onSuccess, onFailed) {1698 var that = this,1699 frameId = (transportLogic.foreverFrame.count += 1),1700 url,1701 frame = createFrame(),1702 frameLoadHandler = function () {1703 connection.log("Forever frame iframe finished loading and is no longer receiving messages.");1704 if (!onFailed || !onFailed()) {1705 that.reconnect(connection);1706 }1707 };1708 if (window.EventSource) {1709 // If the browser supports SSE, don't use Forever Frame1710 if (onFailed) {1711 connection.log("Forever Frame is not supported by SignalR on browsers with SSE support.");1712 onFailed();1713 }1714 return;1715 }1716 frame.setAttribute("data-signalr-connection-id", connection.id);1717 // Start preventing loading icon1718 // This will only perform work if the loadPreventer is not attached to another connection.1719 loadPreventer.prevent();1720 // Build the url1721 url = transportLogic.getUrl(connection, this.name);1722 url += "&frameId=" + frameId;1723 // add frame to the document prior to setting URL to avoid caching issues.1724 window.document.documentElement.appendChild(frame);1725 connection.log("Binding to iframe's load event.");1726 if (frame.addEventListener) {1727 frame.addEventListener("load", frameLoadHandler, false);1728 } else if (frame.attachEvent) {1729 frame.attachEvent("onload", frameLoadHandler);1730 }1731 frame.src = url;1732 transportLogic.foreverFrame.connections[frameId] = connection;1733 connection.frame = frame;1734 connection.frameId = frameId;1735 if (onSuccess) {1736 connection.onSuccess = function () {1737 connection.log("Iframe transport started.");1738 onSuccess();1739 };1740 }1741 },1742 reconnect: function (connection) {1743 var that = this;1744 // Need to verify connection state and verify before the setTimeout occurs because an application sleep could occur during the setTimeout duration.1745 if (transportLogic.isConnectedOrReconnecting(connection) && transportLogic.verifyLastActive(connection)) {1746 window.setTimeout(function () {1747 // Verify that we're ok to reconnect.1748 if (!transportLogic.verifyLastActive(connection)) {1749 return;1750 }1751 if (connection.frame && transportLogic.ensureReconnectingState(connection)) {1752 var frame = connection.frame,1753 src = transportLogic.getUrl(connection, that.name, true) + "&frameId=" + connection.frameId;1754 connection.log("Updating iframe src to '" + src + "'.");1755 frame.src = src;1756 }1757 }, connection.reconnectDelay);1758 }1759 },1760 lostConnection: function (connection) {1761 this.reconnect(connection);1762 },1763 send: function (connection, data) {1764 transportLogic.ajaxSend(connection, data);1765 },1766 receive: function (connection, data) {1767 var cw,1768 body,1769 response;1770 if (connection.json !== connection._originalJson) {1771 // If there's a custom JSON parser configured then serialize the object1772 // using the original (browser) JSON parser and then deserialize it using1773 // the custom parser (connection._parseResponse does that). This is so we1774 // can easily send the response from the server as "raw" JSON but still 1775 // support custom JSON deserialization in the browser.1776 data = connection._originalJson.stringify(data);1777 }1778 response = connection._parseResponse(data);1779 transportLogic.processMessages(connection, response, connection.onSuccess);1780 // Protect against connection stopping from a callback trigger within the processMessages above.1781 if (connection.state === $.signalR.connectionState.connected) {1782 // Delete the script & div elements1783 connection.frameMessageCount = (connection.frameMessageCount || 0) + 1;1784 if (connection.frameMessageCount > signalR.transports.foreverFrame.iframeClearThreshold) {1785 connection.frameMessageCount = 0;1786 cw = connection.frame.contentWindow || connection.frame.contentDocument;1787 if (cw && cw.document && cw.document.body) {1788 body = cw.document.body;1789 // Remove all the child elements from the iframe's body to conserver memory1790 while (body.firstChild) {1791 body.removeChild(body.firstChild);1792 }1793 }1794 }1795 }1796 },1797 stop: function (connection) {1798 var cw = null;1799 // Stop attempting to prevent loading icon1800 loadPreventer.cancel();1801 if (connection.frame) {1802 if (connection.frame.stop) {1803 connection.frame.stop();1804 } else {1805 try {1806 cw = connection.frame.contentWindow || connection.frame.contentDocument;1807 if (cw.document && cw.document.execCommand) {1808 cw.document.execCommand("Stop");1809 }1810 }1811 catch (e) {1812 connection.log("Error occured when stopping foreverFrame transport. Message = " + e.message + ".");1813 }1814 }1815 // Ensure the iframe is where we left it1816 if (connection.frame.parentNode === window.document.body) {1817 window.document.body.removeChild(connection.frame);1818 }1819 delete transportLogic.foreverFrame.connections[connection.frameId];1820 connection.frame = null;1821 connection.frameId = null;1822 delete connection.frame;1823 delete connection.frameId;1824 delete connection.onSuccess;1825 delete connection.frameMessageCount;1826 connection.log("Stopping forever frame.");1827 }1828 },1829 abort: function (connection, async) {1830 transportLogic.ajaxAbort(connection, async);1831 },1832 getConnection: function (id) {1833 return transportLogic.foreverFrame.connections[id];1834 },1835 started: function (connection) {1836 if (changeState(connection,1837 signalR.connectionState.reconnecting,1838 signalR.connectionState.connected) === true) {1839 $(connection).triggerHandler(events.onReconnect);1840 }1841 }1842 };1843}(window.jQuery, window));1844/* jquery.signalR.transports.longPolling.js */1845// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.md in the project root for license information.1846/*global window:false */1847/// <reference path="jquery.signalR.transports.common.js" />1848(function ($, window, undefined) {1849 var signalR = $.signalR,1850 events = $.signalR.events,1851 changeState = $.signalR.changeState,1852 isDisconnecting = $.signalR.isDisconnecting,1853 transportLogic = signalR.transports._logic;1854 signalR.transports.longPolling = {1855 name: "longPolling",1856 supportsKeepAlive: function () {1857 return false;1858 },1859 reconnectDelay: 3000,1860 start: function (connection, onSuccess, onFailed) {1861 /// <summary>Starts the long polling connection</summary>1862 /// <param name="connection" type="signalR">The SignalR connection to start</param>1863 var that = this,1864 fireConnect = function () {1865 fireConnect = $.noop;1866 connection.log("LongPolling connected.");1867 onSuccess();1868 },1869 tryFailConnect = function (error) {1870 if (onFailed(error)) {1871 connection.log("LongPolling failed to connect.");1872 return true;1873 }1874 return false;1875 },1876 privateData = connection._,1877 reconnectErrors = 0,1878 fireReconnected = function (instance) {1879 window.clearTimeout(privateData.reconnectTimeoutId);1880 privateData.reconnectTimeoutId = null;1881 if (changeState(instance,1882 signalR.connectionState.reconnecting,1883 signalR.connectionState.connected) === true) {1884 // Successfully reconnected!1885 instance.log("Raising the reconnect event");1886 $(instance).triggerHandler(events.onReconnect);1887 }1888 },1889 // 1 hour1890 maxFireReconnectedTimeout = 3600000;1891 if (connection.pollXhr) {1892 connection.log("Polling xhr requests already exists, aborting.");1893 connection.stop();1894 }1895 connection.messageId = null;1896 privateData.reconnectTimeoutId = null;1897 privateData.pollTimeoutId = window.setTimeout(function () {1898 (function poll(instance, raiseReconnect) {1899 var messageId = instance.messageId,1900 connect = (messageId === null),1901 reconnecting = !connect,1902 polling = !raiseReconnect,1903 url = transportLogic.getUrl(instance, that.name, reconnecting, polling, true /* use Post for longPolling */),1904 postData = {};1905 if (instance.messageId) {1906 postData.messageId = instance.messageId;1907 }1908 if (instance.groupsToken) {1909 postData.groupsToken = instance.groupsToken;1910 }1911 // If we've disconnected during the time we've tried to re-instantiate the poll then stop.1912 if (isDisconnecting(instance) === true) {1913 return;1914 }1915 connection.log("Opening long polling request to '" + url + "'.");1916 instance.pollXhr = transportLogic.ajax(connection, {1917 xhrFields: {1918 onprogress: function () {1919 transportLogic.markLastMessage(connection);1920 }1921 },1922 url: url,1923 type: "POST",1924 contentType: signalR._.defaultContentType,1925 data: postData,1926 timeout: connection._.pollTimeout,1927 success: function (result) {1928 var minData,1929 delay = 0,1930 data,1931 shouldReconnect;1932 connection.log("Long poll complete.");1933 // Reset our reconnect errors so if we transition into a reconnecting state again we trigger1934 // reconnected quickly1935 reconnectErrors = 0;1936 try {1937 // Remove any keep-alives from the beginning of the result1938 minData = connection._parseResponse(result);1939 }1940 catch (error) {1941 transportLogic.handleParseFailure(instance, result, error, tryFailConnect, instance.pollXhr);1942 return;1943 }1944 // If there's currently a timeout to trigger reconnect, fire it now before processing messages1945 if (privateData.reconnectTimeoutId !== null) {1946 fireReconnected(instance);1947 }1948 if (minData) {1949 data = transportLogic.maximizePersistentResponse(minData);1950 }1951 transportLogic.processMessages(instance, minData, fireConnect);1952 if (data &&1953 $.type(data.LongPollDelay) === "number") {1954 delay = data.LongPollDelay;1955 }1956 if (isDisconnecting(instance) === true) {1957 return;1958 }1959 shouldReconnect = data && data.ShouldReconnect;1960 if (shouldReconnect) {1961 // Transition into the reconnecting state1962 // If this fails then that means that the user transitioned the connection into a invalid state in processMessages.1963 if (!transportLogic.ensureReconnectingState(instance)) {1964 return;1965 }1966 }1967 // We never want to pass a raiseReconnect flag after a successful poll. This is handled via the error function1968 if (delay > 0) {1969 privateData.pollTimeoutId = window.setTimeout(function () {1970 poll(instance, shouldReconnect);1971 }, delay);1972 } else {1973 poll(instance, shouldReconnect);1974 }1975 },1976 error: function (data, textStatus) {1977 var error = signalR._.transportError(signalR.resources.longPollFailed, connection.transport, data, instance.pollXhr);1978 // Stop trying to trigger reconnect, connection is in an error state1979 // If we're not in the reconnect state this will noop1980 window.clearTimeout(privateData.reconnectTimeoutId);1981 privateData.reconnectTimeoutId = null;1982 if (textStatus === "abort") {1983 connection.log("Aborted xhr request.");1984 return;1985 }1986 if (!tryFailConnect(error)) {1987 // Increment our reconnect errors, we assume all errors to be reconnect errors1988 // In the case that it's our first error this will cause Reconnect to be fired1989 // after 1 second due to reconnectErrors being = 1.1990 reconnectErrors++;1991 if (connection.state !== signalR.connectionState.reconnecting) {1992 connection.log("An error occurred using longPolling. Status = " + textStatus + ". Response = " + data.responseText + ".");1993 $(instance).triggerHandler(events.onError, [error]);1994 }1995 // We check the state here to verify that we're not in an invalid state prior to verifying Reconnect.1996 // If we're not in connected or reconnecting then the next ensureReconnectingState check will fail and will return.1997 // Therefore we don't want to change that failure code path.1998 if ((connection.state === signalR.connectionState.connected ||1999 connection.state === signalR.connectionState.reconnecting) &&2000 !transportLogic.verifyLastActive(connection)) {2001 return;2002 }2003 // Transition into the reconnecting state2004 // If this fails then that means that the user transitioned the connection into the disconnected or connecting state within the above error handler trigger.2005 if (!transportLogic.ensureReconnectingState(instance)) {2006 return;2007 }2008 // Call poll with the raiseReconnect flag as true after the reconnect delay2009 privateData.pollTimeoutId = window.setTimeout(function () {2010 poll(instance, true);2011 }, that.reconnectDelay);2012 }2013 }2014 });2015 // This will only ever pass after an error has occured via the poll ajax procedure.2016 if (reconnecting && raiseReconnect === true) {2017 // We wait to reconnect depending on how many times we've failed to reconnect.2018 // This is essentially a heuristic that will exponentially increase in wait time before2019 // triggering reconnected. This depends on the "error" handler of Poll to cancel this 2020 // timeout if it triggers before the Reconnected event fires.2021 // The Math.min at the end is to ensure that the reconnect timeout does not overflow.2022 privateData.reconnectTimeoutId = window.setTimeout(function () { fireReconnected(instance); }, Math.min(1000 * (Math.pow(2, reconnectErrors) - 1), maxFireReconnectedTimeout));2023 }2024 }(connection));2025 }, 250); // Have to delay initial poll so Chrome doesn't show loader spinner in tab2026 },2027 lostConnection: function (connection) {2028 if (connection.pollXhr) {2029 connection.pollXhr.abort("lostConnection");2030 }2031 },2032 send: function (connection, data) {2033 transportLogic.ajaxSend(connection, data);2034 },2035 stop: function (connection) {2036 /// <summary>Stops the long polling connection</summary>2037 /// <param name="connection" type="signalR">The SignalR connection to stop</param>2038 window.clearTimeout(connection._.pollTimeoutId);2039 window.clearTimeout(connection._.reconnectTimeoutId);2040 delete connection._.pollTimeoutId;2041 delete connection._.reconnectTimeoutId;2042 if (connection.pollXhr) {2043 connection.pollXhr.abort();2044 connection.pollXhr = null;2045 delete connection.pollXhr;2046 }2047 },2048 abort: function (connection, async) {2049 transportLogic.ajaxAbort(connection, async);2050 }2051 };2052}(window.jQuery, window));2053/* jquery.signalR.hubs.js */2054// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.md in the project root for license information.2055/*global window:false */2056/// <reference path="jquery.signalR.core.js" />2057(function ($, window, undefined) {2058 var eventNamespace = ".hubProxy",2059 signalR = $.signalR;2060 function makeEventName(event) {2061 return event + eventNamespace;2062 }2063 // Equivalent to Array.prototype.map2064 function map(arr, fun, thisp) {2065 var i,2066 length = arr.length,2067 result = [];2068 for (i = 0; i < length; i += 1) {2069 if (arr.hasOwnProperty(i)) {2070 result[i] = fun.call(thisp, arr[i], i, arr);2071 }2072 }2073 return result;2074 }2075 function getArgValue(a) {2076 return $.isFunction(a) ? null : ($.type(a) === "undefined" ? null : a);2077 }2078 function hasMembers(obj) {2079 for (var key in obj) {2080 // If we have any properties in our callback map then we have callbacks and can exit the loop via return2081 if (obj.hasOwnProperty(key)) {2082 return true;2083 }2084 }2085 return false;2086 }2087 function clearInvocationCallbacks(connection, error) {2088 /// <param name="connection" type="hubConnection" />2089 var callbacks = connection._.invocationCallbacks,2090 callback;2091 if (hasMembers(callbacks)) {2092 connection.log("Clearing hub invocation callbacks with error: " + error + ".");2093 }2094 // Reset the callback cache now as we have a local var referencing it2095 connection._.invocationCallbackId = 0;2096 delete connection._.invocationCallbacks;2097 connection._.invocationCallbacks = {};2098 // Loop over the callbacks and invoke them.2099 // We do this using a local var reference and *after* we've cleared the cache2100 // so that if a fail callback itself tries to invoke another method we don't 2101 // end up with its callback in the list we're looping over.2102 for (var callbackId in callbacks) {2103 callback = callbacks[callbackId];2104 callback.method.call(callback.scope, { E: error });2105 }2106 }2107 // hubProxy2108 function hubProxy(hubConnection, hubName) {2109 /// <summary>2110 /// Creates a new proxy object for the given hub connection that can be used to invoke2111 /// methods on server hubs and handle client method invocation requests from the server.2112 /// </summary>2113 return new hubProxy.fn.init(hubConnection, hubName);2114 }2115 hubProxy.fn = hubProxy.prototype = {2116 init: function (connection, hubName) {2117 this.state = {};2118 this.connection = connection;2119 this.hubName = hubName;2120 this._ = {2121 callbackMap: {}2122 };2123 },2124 constructor: hubProxy,2125 hasSubscriptions: function () {2126 return hasMembers(this._.callbackMap);2127 },2128 on: function (eventName, callback) {2129 /// <summary>Wires up a callback to be invoked when a invocation request is received from the server hub.</summary>2130 /// <param name="eventName" type="String">The name of the hub event to register the callback for.</param>2131 /// <param name="callback" type="Function">The callback to be invoked.</param>2132 var that = this,2133 callbackMap = that._.callbackMap;2134 // Normalize the event name to lowercase2135 eventName = eventName.toLowerCase();2136 // If there is not an event registered for this callback yet we want to create its event space in the callback map.2137 if (!callbackMap[eventName]) {2138 callbackMap[eventName] = {};2139 }2140 // Map the callback to our encompassed function2141 callbackMap[eventName][callback] = function (e, data) {2142 callback.apply(that, data);2143 };2144 $(that).bind(makeEventName(eventName), callbackMap[eventName][callback]);2145 return that;2146 },2147 off: function (eventName, callback) {2148 /// <summary>Removes the callback invocation request from the server hub for the given event name.</summary>2149 /// <param name="eventName" type="String">The name of the hub event to unregister the callback for.</param>2150 /// <param name="callback" type="Function">The callback to be invoked.</param>2151 var that = this,2152 callbackMap = that._.callbackMap,2153 callbackSpace;2154 // Normalize the event name to lowercase2155 eventName = eventName.toLowerCase();2156 callbackSpace = callbackMap[eventName];2157 // Verify that there is an event space to unbind2158 if (callbackSpace) {2159 // Only unbind if there's an event bound with eventName and a callback with the specified callback2160 if (callbackSpace[callback]) {2161 $(that).unbind(makeEventName(eventName), callbackSpace[callback]);2162 // Remove the callback from the callback map2163 delete callbackSpace[callback];2164 // Check if there are any members left on the event, if not we need to destroy it.2165 if (!hasMembers(callbackSpace)) {2166 delete callbackMap[eventName];2167 }2168 } else if (!callback) { // Check if we're removing the whole event and we didn't error because of an invalid callback2169 $(that).unbind(makeEventName(eventName));2170 delete callbackMap[eventName];2171 }2172 }2173 return that;2174 },2175 invoke: function (methodName) {2176 /// <summary>Invokes a server hub method with the given arguments.</summary>2177 /// <param name="methodName" type="String">The name of the server hub method.</param>2178 var that = this,2179 connection = that.connection,2180 args = $.makeArray(arguments).slice(1),2181 argValues = map(args, getArgValue),2182 data = { H: that.hubName, M: methodName, A: argValues, I: connection._.invocationCallbackId },2183 d = $.Deferred(),2184 callback = function (minResult) {2185 var result = that._maximizeHubResponse(minResult),2186 source,2187 error;2188 // Update the hub state2189 $.extend(that.state, result.State);2190 if (result.Progress) {2191 if (d.notifyWith) {2192 // Progress is only supported in jQuery 1.7+2193 d.notifyWith(that, [result.Progress.Data]);2194 } else if(!connection._.progressjQueryVersionLogged) {2195 connection.log("A hub method invocation progress update was received but the version of jQuery in use (" + $.prototype.jquery + ") does not support progress updates. Upgrade to jQuery 1.7+ to receive progress notifications.");2196 connection._.progressjQueryVersionLogged = true;2197 }2198 } else if (result.Error) {2199 // Server hub method threw an exception, log it & reject the deferred2200 if (result.StackTrace) {2201 connection.log(result.Error + "\n" + result.StackTrace + ".");2202 }2203 // result.ErrorData is only set if a HubException was thrown2204 source = result.IsHubException ? "HubException" : "Exception";2205 error = signalR._.error(result.Error, source);2206 error.data = result.ErrorData;2207 connection.log(that.hubName + "." + methodName + " failed to execute. Error: " + error.message);2208 d.rejectWith(that, [error]);2209 } else {2210 // Server invocation succeeded, resolve the deferred2211 connection.log("Invoked " + that.hubName + "." + methodName);2212 d.resolveWith(that, [result.Result]);2213 }2214 };2215 connection._.invocationCallbacks[connection._.invocationCallbackId.toString()] = { scope: that, method: callback };2216 connection._.invocationCallbackId += 1;2217 if (!$.isEmptyObject(that.state)) {2218 data.S = that.state;2219 }2220 connection.log("Invoking " + that.hubName + "." + methodName);2221 connection.send(data);2222 return d.promise();2223 },2224 _maximizeHubResponse: function (minHubResponse) {2225 return {2226 State: minHubResponse.S,2227 Result: minHubResponse.R,2228 Progress: minHubResponse.P ? {2229 Id: minHubResponse.P.I,2230 Data: minHubResponse.P.D2231 } : null,2232 Id: minHubResponse.I,2233 IsHubException: minHubResponse.H,2234 Error: minHubResponse.E,2235 StackTrace: minHubResponse.T,2236 ErrorData: minHubResponse.D2237 };2238 }2239 };2240 hubProxy.fn.init.prototype = hubProxy.fn;2241 // hubConnection2242 function hubConnection(url, options) {2243 /// <summary>Creates a new hub connection.</summary>2244 /// <param name="url" type="String">[Optional] The hub route url, defaults to "/signalr".</param>2245 /// <param name="options" type="Object">[Optional] Settings to use when creating the hubConnection.</param>2246 var settings = {2247 qs: null,2248 logging: false,2249 useDefaultPath: true2250 };2251 $.extend(settings, options);2252 if (!url || settings.useDefaultPath) {2253 url = (url || "") + "/signalr";2254 }2255 return new hubConnection.fn.init(url, settings);2256 }...
jquery.signalR-1.1.2.js
Source:jquery.signalR-1.1.2.js
...587 // Check if the keep alive has completely timed out588 if (timeElapsed >= keepAliveData.timeout) {589 connection.log("Keep alive timed out. Notifying transport that connection has been lost.");590 // Notify transport that the connection has been lost591 connection.transport.lostConnection(connection);592 }593 else if (timeElapsed >= keepAliveData.timeoutWarning) {594 // This is to assure that the user only gets a single warning595 if (!keepAliveData.userNotified) {596 connection.log("Keep alive has been missed, connection may be dead/slow.");597 $(connection).triggerHandler(events.onConnectionSlow);598 keepAliveData.userNotified = true;599 }600 }601 else {602 keepAliveData.userNotified = false;603 }604 }605 // Verify we're monitoring the keep alive606 // We don't want this as a part of the inner if statement above because we want keep alives to continue to be checked607 // in the event that the server comes back online (if it goes offline).608 if (keepAliveData.monitoring) {609 window.setTimeout(function () {610 checkIfAlive(connection);611 }, keepAliveData.checkInterval);612 }613 }614 function isConnectedOrReconnecting(connection) {615 return connection.state === signalR.connectionState.connected ||616 connection.state === signalR.connectionState.reconnecting;617 }618 signalR.transports._logic = {619 pingServer: function (connection, transport) {620 /// <summary>Pings the server</summary>621 /// <param name="connection" type="signalr">Connection associated with the server ping</param>622 /// <returns type="signalR" />623 var baseUrl = transport === "webSockets" ? "" : connection.baseUrl,624 url = baseUrl + connection.appRelativeUrl + "/ping",625 deferral = $.Deferred();626 url = this.addQs(url, connection);627 $.ajax({628 url: url,629 global: false,630 cache: false,631 type: "GET",632 contentType: connection.contentType,633 data: {},634 dataType: connection.ajaxDataType,635 success: function (data) {636 if (data.Response === "pong") {637 deferral.resolve();638 }639 else {640 deferral.reject("SignalR: Invalid ping response when pinging server: " + (data.responseText || data.statusText));641 }642 },643 error: function (data) {644 deferral.reject("SignalR: Error pinging server: " + (data.responseText || data.statusText));645 }646 });647 return deferral.promise();648 },649 addQs: function (url, connection) {650 var appender = url.indexOf("?") !== -1 ? "&" : "?",651 firstChar;652 if (!connection.qs) {653 return url;654 }655 if (typeof (connection.qs) === "object") {656 return url + appender + $.param(connection.qs);657 }658 if (typeof (connection.qs) === "string") {659 firstChar = connection.qs.charAt(0);660 if (firstChar === "?" || firstChar === "&") {661 appender = "";662 }663 return url + appender + connection.qs;664 }665 throw new Error("Connections query string property must be either a string or object.");666 },667 getUrl: function (connection, transport, reconnecting, poll) {668 /// <summary>Gets the url for making a GET based connect request</summary>669 var baseUrl = transport === "webSockets" ? "" : connection.baseUrl,670 url = baseUrl + connection.appRelativeUrl,671 qs = "transport=" + transport + "&connectionToken=" + window.encodeURIComponent(connection.token);672 if (connection.data) {673 qs += "&connectionData=" + window.encodeURIComponent(connection.data);674 }675 if (connection.groupsToken) {676 qs += "&groupsToken=" + window.encodeURIComponent(connection.groupsToken);677 }678 if (!reconnecting) {679 url += "/connect";680 } else {681 if (poll) {682 // longPolling transport specific683 url += "/poll";684 } else {685 url += "/reconnect";686 }687 if (connection.messageId) {688 qs += "&messageId=" + window.encodeURIComponent(connection.messageId);689 }690 }691 url += "?" + qs;692 url = this.addQs(url, connection);693 url += "&tid=" + Math.floor(Math.random() * 11);694 return url;695 },696 maximizePersistentResponse: function (minPersistentResponse) {697 return {698 MessageId: minPersistentResponse.C,699 Messages: minPersistentResponse.M,700 Disconnect: typeof (minPersistentResponse.D) !== "undefined" ? true : false,701 TimedOut: typeof (minPersistentResponse.T) !== "undefined" ? true : false,702 LongPollDelay: minPersistentResponse.L,703 GroupsToken: minPersistentResponse.G704 };705 },706 updateGroups: function (connection, groupsToken) {707 if (groupsToken) {708 connection.groupsToken = groupsToken;709 }710 },711 ajaxSend: function (connection, data) {712 var url = connection.url + "/send" + "?transport=" + connection.transport.name + "&connectionToken=" + window.encodeURIComponent(connection.token);713 url = this.addQs(url, connection);714 return $.ajax({715 url: url,716 global: false,717 type: connection.ajaxDataType === "jsonp" ? "GET" : "POST",718 contentType: signalR._.defaultContentType,719 dataType: connection.ajaxDataType,720 data: {721 data: data722 },723 success: function (result) {724 if (result) {725 $(connection).triggerHandler(events.onReceived, [result]);726 }727 },728 error: function (errData, textStatus) {729 if (textStatus === "abort" || textStatus === "parsererror") {730 // The parsererror happens for sends that don't return any data, and hence731 // don't write the jsonp callback to the response. This is harder to fix on the server732 // so just hack around it on the client for now.733 return;734 }735 $(connection).triggerHandler(events.onError, [errData]);736 }737 });738 },739 ajaxAbort: function (connection, async) {740 if (typeof (connection.transport) === "undefined") {741 return;742 }743 // Async by default unless explicitly overidden744 async = typeof async === "undefined" ? true : async;745 var url = connection.url + "/abort" + "?transport=" + connection.transport.name + "&connectionToken=" + window.encodeURIComponent(connection.token);746 url = this.addQs(url, connection);747 $.ajax({748 url: url,749 async: async,750 timeout: 1000,751 global: false,752 type: "POST",753 contentType: connection.contentType,754 dataType: connection.ajaxDataType,755 data: {}756 });757 connection.log("Fired ajax abort async = " + async);758 },759 processMessages: function (connection, minData) {760 var data;761 // Transport can be null if we've just closed the connection762 if (connection.transport) {763 var $connection = $(connection);764 // If our transport supports keep alive then we need to update the last keep alive time stamp.765 // Very rarely the transport can be null.766 if (connection.transport.supportsKeepAlive && connection.keepAliveData.activated) {767 this.updateKeepAlive(connection);768 }769 if (!minData) {770 return;771 }772 data = this.maximizePersistentResponse(minData);773 if (data.Disconnect) {774 connection.log("Disconnect command received from server");775 // Disconnected by the server776 connection.stop(false, false);777 return;778 }779 this.updateGroups(connection, data.GroupsToken);780 if (data.Messages) {781 $.each(data.Messages, function (index, message) {782 $connection.triggerHandler(events.onReceived, [message]);783 });784 }785 if (data.MessageId) {786 connection.messageId = data.MessageId;787 }788 }789 },790 monitorKeepAlive: function (connection) {791 var keepAliveData = connection.keepAliveData,792 that = this;793 // If we haven't initiated the keep alive timeouts then we need to794 if (!keepAliveData.monitoring) {795 keepAliveData.monitoring = true;796 // Initialize the keep alive time stamp ping797 that.updateKeepAlive(connection);798 // Save the function so we can unbind it on stop799 connection.keepAliveData.reconnectKeepAliveUpdate = function () {800 that.updateKeepAlive(connection);801 };802 // Update Keep alive on reconnect803 $(connection).bind(events.onReconnect, connection.keepAliveData.reconnectKeepAliveUpdate);804 connection.log("Now monitoring keep alive with a warning timeout of " + keepAliveData.timeoutWarning + " and a connection lost timeout of " + keepAliveData.timeout);805 // Start the monitoring of the keep alive806 checkIfAlive(connection);807 }808 else {809 connection.log("Tried to monitor keep alive but it's already being monitored");810 }811 },812 stopMonitoringKeepAlive: function (connection) {813 var keepAliveData = connection.keepAliveData;814 // Only attempt to stop the keep alive monitoring if its being monitored815 if (keepAliveData.monitoring) {816 // Stop monitoring817 keepAliveData.monitoring = false;818 // Remove the updateKeepAlive function from the reconnect event819 $(connection).unbind(events.onReconnect, connection.keepAliveData.reconnectKeepAliveUpdate);820 // Clear all the keep alive data821 connection.keepAliveData = {};822 connection.log("Stopping the monitoring of the keep alive");823 }824 },825 updateKeepAlive: function (connection) {826 connection.keepAliveData.lastKeepAlive = new Date();827 },828 ensureReconnectingState: function (connection) {829 if (changeState(connection,830 signalR.connectionState.connected,831 signalR.connectionState.reconnecting) === true) {832 $(connection).triggerHandler(events.onReconnecting);833 }834 return connection.state === signalR.connectionState.reconnecting;835 },836 clearReconnectTimeout: function (connection) {837 if (connection && connection._.reconnectTimeout) {838 window.clearTimeout(connection._.reconnectTimeout);839 delete connection._.reconnectTimeout;840 }841 },842 reconnect: function (connection, transportName) {843 var transport = signalR.transports[transportName],844 that = this;845 // We should only set a reconnectTimeout if we are currently connected846 // and a reconnectTimeout isn't already set.847 if (isConnectedOrReconnecting(connection) && !connection._.reconnectTimeout) {848 connection._.reconnectTimeout = window.setTimeout(function () {849 transport.stop(connection);850 if (that.ensureReconnectingState(connection)) {851 connection.log(transportName + " reconnecting");852 transport.start(connection);853 }854 }, connection.reconnectDelay);855 }856 },857 foreverFrame: {858 count: 0,859 connections: {}860 }861 };862}(window.jQuery, window));863/* jquery.signalR.transports.webSockets.js */864// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.md in the project root for license information.865/*global window:false */866/// <reference path="jquery.signalR.transports.common.js" />867(function ($, window) {868 "use strict";869 var signalR = $.signalR,870 events = $.signalR.events,871 changeState = $.signalR.changeState,872 transportLogic = signalR.transports._logic;873 signalR.transports.webSockets = {874 name: "webSockets",875 supportsKeepAlive: true,876 send: function (connection, data) {877 connection.socket.send(data);878 },879 start: function (connection, onSuccess, onFailed) {880 var url,881 opened = false,882 that = this,883 reconnecting = !onSuccess,884 $connection = $(connection);885 if (!window.WebSocket) {886 onFailed();887 return;888 }889 if (!connection.socket) {890 if (connection.webSocketServerUrl) {891 url = connection.webSocketServerUrl;892 }893 else {894 url = connection.wsProtocol + connection.host;895 }896 url += transportLogic.getUrl(connection, this.name, reconnecting);897 connection.log("Connecting to websocket endpoint '" + url + "'");898 connection.socket = new window.WebSocket(url);899 connection.socket.onopen = function () {900 opened = true;901 connection.log("Websocket opened");902 transportLogic.clearReconnectTimeout(connection);903 if (onSuccess) {904 onSuccess();905 } else if (changeState(connection,906 signalR.connectionState.reconnecting,907 signalR.connectionState.connected) === true) {908 $connection.triggerHandler(events.onReconnect);909 }910 };911 connection.socket.onclose = function (event) {912 // Only handle a socket close if the close is from the current socket.913 // Sometimes on disconnect the server will push down an onclose event914 // to an expired socket.915 if (this === connection.socket) {916 if (!opened) {917 if (onFailed) {918 onFailed();919 }920 else if (reconnecting) {921 that.reconnect(connection);922 }923 return;924 }925 else if (typeof event.wasClean !== "undefined" && event.wasClean === false) {926 // Ideally this would use the websocket.onerror handler (rather than checking wasClean in onclose) but927 // I found in some circumstances Chrome won't call onerror. This implementation seems to work on all browsers.928 $(connection).triggerHandler(events.onError, [event.reason]);929 connection.log("Unclean disconnect from websocket." + event.reason);930 }931 else {932 connection.log("Websocket closed");933 }934 that.reconnect(connection);935 }936 };937 connection.socket.onmessage = function (event) {938 var data = window.JSON.parse(event.data),939 $connection = $(connection);940 if (data) {941 // data.M is PersistentResponse.Messages942 if ($.isEmptyObject(data) || data.M) {943 transportLogic.processMessages(connection, data);944 } else {945 // For websockets we need to trigger onReceived946 // for callbacks to outgoing hub calls.947 $connection.triggerHandler(events.onReceived, [data]);948 }949 }950 };951 }952 },953 reconnect: function (connection) {954 transportLogic.reconnect(connection, this.name);955 },956 lostConnection: function (connection) {957 this.reconnect(connection);958 },959 stop: function (connection) {960 // Don't trigger a reconnect after stopping961 transportLogic.clearReconnectTimeout(connection);962 if (connection.socket !== null) {963 connection.log("Closing the Websocket");964 connection.socket.close();965 connection.socket = null;966 }967 },968 abort: function (connection) {969 }970 };971}(window.jQuery, window));972/* jquery.signalR.transports.serverSentEvents.js */973// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.md in the project root for license information.974/*global window:false */975/// <reference path="jquery.signalR.transports.common.js" />976(function ($, window) {977 "use strict";978 var signalR = $.signalR,979 events = $.signalR.events,980 changeState = $.signalR.changeState,981 transportLogic = signalR.transports._logic;982 signalR.transports.serverSentEvents = {983 name: "serverSentEvents",984 supportsKeepAlive: true,985 timeOut: 3000,986 start: function (connection, onSuccess, onFailed) {987 var that = this,988 opened = false,989 $connection = $(connection),990 reconnecting = !onSuccess,991 url,992 connectTimeOut;993 if (connection.eventSource) {994 connection.log("The connection already has an event source. Stopping it.");995 connection.stop();996 }997 if (!window.EventSource) {998 if (onFailed) {999 connection.log("This browser doesn't support SSE.");1000 onFailed();1001 }1002 return;1003 }1004 url = transportLogic.getUrl(connection, this.name, reconnecting);1005 try {1006 connection.log("Attempting to connect to SSE endpoint '" + url + "'");1007 connection.eventSource = new window.EventSource(url);1008 }1009 catch (e) {1010 connection.log("EventSource failed trying to connect with error " + e.Message);1011 if (onFailed) {1012 // The connection failed, call the failed callback1013 onFailed();1014 }1015 else {1016 $connection.triggerHandler(events.onError, [e]);1017 if (reconnecting) {1018 // If we were reconnecting, rather than doing initial connect, then try reconnect again1019 that.reconnect(connection);1020 }1021 }1022 return;1023 }1024 // After connecting, if after the specified timeout there's no response stop the connection1025 // and raise on failed1026 connectTimeOut = window.setTimeout(function () {1027 if (opened === false) {1028 connection.log("EventSource timed out trying to connect");1029 connection.log("EventSource readyState: " + connection.eventSource.readyState);1030 if (!reconnecting) {1031 that.stop(connection);1032 }1033 if (reconnecting) {1034 // If we're reconnecting and the event source is attempting to connect,1035 // don't keep retrying. This causes duplicate connections to spawn.1036 if (connection.eventSource.readyState !== window.EventSource.CONNECTING &&1037 connection.eventSource.readyState !== window.EventSource.OPEN) {1038 // If we were reconnecting, rather than doing initial connect, then try reconnect again1039 that.reconnect(connection);1040 }1041 } else if (onFailed) {1042 onFailed();1043 }1044 }1045 },1046 that.timeOut);1047 connection.eventSource.addEventListener("open", function (e) {1048 connection.log("EventSource connected");1049 if (connectTimeOut) {1050 window.clearTimeout(connectTimeOut);1051 }1052 transportLogic.clearReconnectTimeout(connection);1053 if (opened === false) {1054 opened = true;1055 if (onSuccess) {1056 onSuccess();1057 } else if (changeState(connection,1058 signalR.connectionState.reconnecting,1059 signalR.connectionState.connected) === true) {1060 // If there's no onSuccess handler we assume this is a reconnect1061 $connection.triggerHandler(events.onReconnect);1062 }1063 }1064 }, false);1065 connection.eventSource.addEventListener("message", function (e) {1066 // process messages1067 if (e.data === "initialized") {1068 return;1069 }1070 transportLogic.processMessages(connection, window.JSON.parse(e.data));1071 }, false);1072 connection.eventSource.addEventListener("error", function (e) {1073 // Only handle an error if the error is from the current Event Source.1074 // Sometimes on disconnect the server will push down an error event1075 // to an expired Event Source.1076 if (this === connection.eventSource) {1077 if (!opened) {1078 if (onFailed) {1079 onFailed();1080 }1081 return;1082 }1083 connection.log("EventSource readyState: " + connection.eventSource.readyState);1084 if (e.eventPhase === window.EventSource.CLOSED) {1085 // We don't use the EventSource's native reconnect function as it1086 // doesn't allow us to change the URL when reconnecting. We need1087 // to change the URL to not include the /connect suffix, and pass1088 // the last message id we received.1089 connection.log("EventSource reconnecting due to the server connection ending");1090 that.reconnect(connection);1091 } else {1092 // connection error1093 connection.log("EventSource error");1094 $connection.triggerHandler(events.onError);1095 }1096 }1097 }, false);1098 },1099 reconnect: function (connection) {1100 transportLogic.reconnect(connection, this.name);1101 },1102 lostConnection: function (connection) {1103 this.reconnect(connection);1104 },1105 send: function (connection, data) {1106 transportLogic.ajaxSend(connection, data);1107 },1108 stop: function (connection) {1109 // Don't trigger a reconnect after stopping1110 transportLogic.clearReconnectTimeout(connection);1111 if (connection && connection.eventSource) {1112 connection.log("EventSource calling close()");1113 connection.eventSource.close();1114 connection.eventSource = null;1115 delete connection.eventSource;1116 }1117 },1118 abort: function (connection, async) {1119 transportLogic.ajaxAbort(connection, async);1120 }1121 };1122}(window.jQuery, window));1123/* jquery.signalR.transports.foreverFrame.js */1124// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.md in the project root for license information.1125/*global window:false */1126/// <reference path="jquery.signalR.transports.common.js" />1127(function ($, window) {1128 "use strict";1129 var signalR = $.signalR,1130 events = $.signalR.events,1131 changeState = $.signalR.changeState,1132 transportLogic = signalR.transports._logic,1133 // Used to prevent infinite loading icon spins in older versions of ie1134 // We build this object inside a closure so we don't pollute the rest of 1135 // the foreverFrame transport with unnecessary functions/utilities.1136 loadPreventer = (function () {1137 var loadingFixIntervalId = null,1138 loadingFixInterval = 1000,1139 attachedTo = 0;1140 return {1141 prevent: function () {1142 // Prevent additional iframe removal procedures from newer browsers1143 if (signalR._.ieVersion <= 8) {1144 // We only ever want to set the interval one time, so on the first attachedTo1145 if (attachedTo === 0) {1146 // Create and destroy iframe every 3 seconds to prevent loading icon, super hacky1147 loadingFixIntervalId = window.setInterval(function () {1148 var tempFrame = $("<iframe style='position:absolute;top:0;left:0;width:0;height:0;visibility:hidden;' src=''></iframe>");1149 $("body").append(tempFrame);1150 tempFrame.remove();1151 tempFrame = null;1152 }, loadingFixInterval);1153 }1154 attachedTo++;1155 }1156 },1157 cancel: function () { 1158 // Only clear the interval if there's only one more object that the loadPreventer is attachedTo1159 if (attachedTo === 1) {1160 window.clearInterval(loadingFixIntervalId);1161 }1162 if (attachedTo > 0) {1163 attachedTo--;1164 }1165 }1166 };1167 })();1168 signalR.transports.foreverFrame = {1169 name: "foreverFrame",1170 supportsKeepAlive: true,1171 timeOut: 3000,1172 start: function (connection, onSuccess, onFailed) {1173 var that = this,1174 frameId = (transportLogic.foreverFrame.count += 1),1175 url,1176 frame = $("<iframe data-signalr-connection-id='" + connection.id + "' style='position:absolute;top:0;left:0;width:0;height:0;visibility:hidden;' src=''></iframe>");1177 if (window.EventSource) {1178 // If the browser supports SSE, don't use Forever Frame1179 if (onFailed) {1180 connection.log("This browser supports SSE, skipping Forever Frame.");1181 onFailed();1182 }1183 return;1184 }1185 // Start preventing loading icon1186 // This will only perform work if the loadPreventer is not attached to another connection.1187 loadPreventer.prevent();1188 // Build the url1189 url = transportLogic.getUrl(connection, this.name);1190 url += "&frameId=" + frameId;1191 // Set body prior to setting URL to avoid caching issues.1192 $("body").append(frame);1193 frame.prop("src", url);1194 transportLogic.foreverFrame.connections[frameId] = connection;1195 connection.log("Binding to iframe's readystatechange event.");1196 frame.bind("readystatechange", function () {1197 if ($.inArray(this.readyState, ["loaded", "complete"]) >= 0) {1198 connection.log("Forever frame iframe readyState changed to " + this.readyState + ", reconnecting");1199 that.reconnect(connection);1200 }1201 });1202 connection.frame = frame[0];1203 connection.frameId = frameId;1204 if (onSuccess) {1205 connection.onSuccess = onSuccess;1206 }1207 // After connecting, if after the specified timeout there's no response stop the connection1208 // and raise on failed1209 window.setTimeout(function () {1210 if (connection.onSuccess) {1211 connection.log("Failed to connect using forever frame source, it timed out after " + that.timeOut + "ms.");1212 that.stop(connection);1213 if (onFailed) {1214 onFailed();1215 }1216 }1217 }, that.timeOut);1218 },1219 reconnect: function (connection) {1220 var that = this;1221 window.setTimeout(function () {1222 if (connection.frame && transportLogic.ensureReconnectingState(connection)) {1223 var frame = connection.frame,1224 src = transportLogic.getUrl(connection, that.name, true) + "&frameId=" + connection.frameId;1225 connection.log("Updating iframe src to '" + src + "'.");1226 frame.src = src;1227 }1228 }, connection.reconnectDelay);1229 },1230 lostConnection: function (connection) {1231 this.reconnect(connection);1232 },1233 send: function (connection, data) {1234 transportLogic.ajaxSend(connection, data);1235 },1236 receive: function (connection, data) {1237 var cw;1238 transportLogic.processMessages(connection, data);1239 // Delete the script & div elements1240 connection.frameMessageCount = (connection.frameMessageCount || 0) + 1;1241 if (connection.frameMessageCount > 50) {1242 connection.frameMessageCount = 0;1243 cw = connection.frame.contentWindow || connection.frame.contentDocument;1244 if (cw && cw.document) {1245 $("body", cw.document).empty();1246 }1247 }1248 },1249 stop: function (connection) {1250 var cw = null;1251 // Stop attempting to prevent loading icon1252 loadPreventer.cancel();1253 if (connection.frame) {1254 if (connection.frame.stop) {1255 connection.frame.stop();1256 } else {1257 try {1258 cw = connection.frame.contentWindow || connection.frame.contentDocument;1259 if (cw.document && cw.document.execCommand) {1260 cw.document.execCommand("Stop");1261 }1262 }1263 catch (e) {1264 connection.log("SignalR: Error occured when stopping foreverFrame transport. Message = " + e.message);1265 }1266 }1267 $(connection.frame).remove();1268 delete transportLogic.foreverFrame.connections[connection.frameId];1269 connection.frame = null;1270 connection.frameId = null;1271 delete connection.frame;1272 delete connection.frameId;1273 connection.log("Stopping forever frame");1274 }1275 },1276 abort: function (connection, async) {1277 transportLogic.ajaxAbort(connection, async);1278 },1279 getConnection: function (id) {1280 return transportLogic.foreverFrame.connections[id];1281 },1282 started: function (connection) {1283 if (connection.onSuccess) {1284 connection.onSuccess();1285 connection.onSuccess = null;1286 delete connection.onSuccess;1287 } else if (changeState(connection,1288 signalR.connectionState.reconnecting,1289 signalR.connectionState.connected) === true) {1290 // If there's no onSuccess handler we assume this is a reconnect1291 $(connection).triggerHandler(events.onReconnect);1292 }1293 }1294 };1295}(window.jQuery, window));1296/* jquery.signalR.transports.longPolling.js */1297// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.md in the project root for license information.1298/*global window:false */1299/// <reference path="jquery.signalR.transports.common.js" />1300(function ($, window) {1301 "use strict";1302 var signalR = $.signalR,1303 events = $.signalR.events,1304 changeState = $.signalR.changeState,1305 isDisconnecting = $.signalR.isDisconnecting,1306 transportLogic = signalR.transports._logic;1307 signalR.transports.longPolling = {1308 name: "longPolling",1309 supportsKeepAlive: false,1310 reconnectDelay: 3000,1311 init: function (connection, onComplete) {1312 /// <summary>Pings the server to ensure availability</summary>1313 /// <param name="connection" type="signalr">Connection associated with the server ping</param>1314 /// <param name="onComplete" type="Function">Callback to call once initialization has completed</param>1315 var that = this,1316 pingLoop,1317 // pingFail is used to loop the re-ping behavior. When we fail we want to re-try.1318 pingFail = function (reason) {1319 if (isDisconnecting(connection) === false) {1320 connection.log("SignalR: Server ping failed because '" + reason + "', re-trying ping.");1321 window.setTimeout(pingLoop, that.reconnectDelay);1322 }1323 };1324 connection.log("SignalR: Initializing long polling connection with server.");1325 pingLoop = function () {1326 // Ping the server, on successful ping call the onComplete method, otherwise if we fail call the pingFail1327 transportLogic.pingServer(connection, that.name).done(onComplete).fail(pingFail);1328 };1329 pingLoop();1330 },1331 start: function (connection, onSuccess, onFailed) {1332 /// <summary>Starts the long polling connection</summary>1333 /// <param name="connection" type="signalR">The SignalR connection to start</param>1334 var that = this,1335 initialConnectedFired = false,1336 fireConnect = function () {1337 if (initialConnectedFired) {1338 return;1339 }1340 initialConnectedFired = true;1341 onSuccess();1342 connection.log("Longpolling connected");1343 },1344 reconnectErrors = 0,1345 reconnectTimeoutId = null,1346 fireReconnected = function (instance) {1347 window.clearTimeout(reconnectTimeoutId);1348 reconnectTimeoutId = null;1349 if (changeState(connection,1350 signalR.connectionState.reconnecting,1351 signalR.connectionState.connected) === true) {1352 // Successfully reconnected!1353 connection.log("Raising the reconnect event");1354 $(instance).triggerHandler(events.onReconnect);1355 }1356 },1357 // 1 hour1358 maxFireReconnectedTimeout = 3600000;1359 if (connection.pollXhr) {1360 connection.log("Polling xhr requests already exists, aborting.");1361 connection.stop();1362 }1363 // We start with an initialization procedure which pings the server to verify that it is there.1364 // On scucessful initialization we'll then proceed with starting the transport.1365 that.init(connection, function () {1366 connection.messageId = null;1367 window.setTimeout(function () {1368 (function poll(instance, raiseReconnect) {1369 var messageId = instance.messageId,1370 connect = (messageId === null),1371 reconnecting = !connect,1372 polling = !raiseReconnect,1373 url = transportLogic.getUrl(instance, that.name, reconnecting, polling);1374 // If we've disconnected during the time we've tried to re-instantiate the poll then stop.1375 if (isDisconnecting(instance) === true) {1376 return;1377 }1378 connection.log("Attempting to connect to '" + url + "' using longPolling.");1379 instance.pollXhr = $.ajax({1380 url: url,1381 global: false,1382 cache: false,1383 type: "GET",1384 dataType: connection.ajaxDataType,1385 contentType: connection.contentType,1386 success: function (minData) {1387 var delay = 0,1388 data;1389 // Reset our reconnect errors so if we transition into a reconnecting state again we trigger1390 // reconnected quickly1391 reconnectErrors = 0;1392 // If there's currently a timeout to trigger reconnect, fire it now before processing messages1393 if (reconnectTimeoutId !== null) {1394 fireReconnected();1395 }1396 fireConnect();1397 if (minData) {1398 data = transportLogic.maximizePersistentResponse(minData);1399 }1400 transportLogic.processMessages(instance, minData);1401 if (data &&1402 $.type(data.LongPollDelay) === "number") {1403 delay = data.LongPollDelay;1404 }1405 if (data && data.Disconnect) {1406 return;1407 }1408 if (isDisconnecting(instance) === true) {1409 return;1410 }1411 // We never want to pass a raiseReconnect flag after a successful poll. This is handled via the error function1412 if (delay > 0) {1413 window.setTimeout(function () {1414 poll(instance, false);1415 }, delay);1416 } else {1417 poll(instance, false);1418 }1419 },1420 error: function (data, textStatus) {1421 // Stop trying to trigger reconnect, connection is in an error state1422 // If we're not in the reconnect state this will noop1423 window.clearTimeout(reconnectTimeoutId);1424 reconnectTimeoutId = null;1425 if (textStatus === "abort") {1426 connection.log("Aborted xhr requst.");1427 return;1428 }1429 // Increment our reconnect errors, we assume all errors to be reconnect errors1430 // In the case that it's our first error this will cause Reconnect to be fired1431 // after 1 second due to reconnectErrors being = 1.1432 reconnectErrors++;1433 if (connection.state !== signalR.connectionState.reconnecting) {1434 connection.log("An error occurred using longPolling. Status = " + textStatus + ". " + data.responseText);1435 $(instance).triggerHandler(events.onError, [data.responseText]);1436 }1437 // Transition into the reconnecting state1438 transportLogic.ensureReconnectingState(instance);1439 // If we've errored out we need to verify that the server is still there, so re-start initialization process1440 // This will ping the server until it successfully gets a response.1441 that.init(instance, function () {1442 // Call poll with the raiseReconnect flag as true1443 poll(instance, true);1444 });1445 }1446 });1447 // This will only ever pass after an error has occured via the poll ajax procedure.1448 if (reconnecting && raiseReconnect === true) {1449 // We wait to reconnect depending on how many times we've failed to reconnect.1450 // This is essentially a heuristic that will exponentially increase in wait time before1451 // triggering reconnected. This depends on the "error" handler of Poll to cancel this 1452 // timeout if it triggers before the Reconnected event fires.1453 // The Math.min at the end is to ensure that the reconnect timeout does not overflow.1454 reconnectTimeoutId = window.setTimeout(function () { fireReconnected(instance); }, Math.min(1000 * (Math.pow(2, reconnectErrors) - 1), maxFireReconnectedTimeout));1455 }1456 }(connection));1457 // Set an arbitrary timeout to trigger onSuccess, this will alot for enough time on the server to wire up the connection.1458 // Will be fixed by #1189 and this code can be modified to not be a timeout1459 window.setTimeout(function () {1460 // Trigger the onSuccess() method because we've now instantiated a connection1461 fireConnect();1462 }, 250);1463 }, 250); // Have to delay initial poll so Chrome doesn't show loader spinner in tab1464 });1465 },1466 lostConnection: function (connection) {1467 throw new Error("Lost Connection not handled for LongPolling");1468 },1469 send: function (connection, data) {1470 transportLogic.ajaxSend(connection, data);1471 },1472 stop: function (connection) {1473 /// <summary>Stops the long polling connection</summary>1474 /// <param name="connection" type="signalR">The SignalR connection to stop</param>1475 if (connection.pollXhr) {1476 connection.pollXhr.abort();1477 connection.pollXhr = null;1478 delete connection.pollXhr;1479 }1480 },1481 abort: function (connection, async) {1482 transportLogic.ajaxAbort(connection, async);1483 }1484 };1485}(window.jQuery, window));1486/* jquery.signalR.hubs.js */1487// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.md in the project root for license information.1488/*global window:false */1489/// <reference path="jquery.signalR.core.js" />1490(function ($, window) {1491 "use strict";1492 // we use a global id for tracking callbacks so the server doesn't have to send extra info like hub name1493 var callbackId = 0,1494 callbacks = {},1495 eventNamespace = ".hubProxy";1496 function makeEventName(event) {1497 return event + eventNamespace;1498 }1499 // Equivalent to Array.prototype.map1500 function map(arr, fun, thisp) {1501 var i,1502 length = arr.length,1503 result = [];1504 for (i = 0; i < length; i += 1) {1505 if (arr.hasOwnProperty(i)) {1506 result[i] = fun.call(thisp, arr[i], i, arr);1507 }1508 }1509 return result;1510 }1511 function getArgValue(a) {1512 return $.isFunction(a) ? null : ($.type(a) === "undefined" ? null : a);1513 }1514 function hasMembers(obj) {1515 for (var key in obj) {1516 // If we have any properties in our callback map then we have callbacks and can exit the loop via return1517 if (obj.hasOwnProperty(key)) {1518 return true;1519 }1520 }1521 return false;1522 }1523 // hubProxy1524 function hubProxy(hubConnection, hubName) {1525 /// <summary>1526 /// Creates a new proxy object for the given hub connection that can be used to invoke1527 /// methods on server hubs and handle client method invocation requests from the server.1528 /// </summary>1529 return new hubProxy.fn.init(hubConnection, hubName);1530 }1531 hubProxy.fn = hubProxy.prototype = {1532 init: function (connection, hubName) {1533 this.state = {};1534 this.connection = connection;1535 this.hubName = hubName;1536 this._ = {1537 callbackMap: {}1538 };1539 },1540 hasSubscriptions: function () {1541 return hasMembers(this._.callbackMap);1542 },1543 on: function (eventName, callback) {1544 /// <summary>Wires up a callback to be invoked when a invocation request is received from the server hub.</summary>1545 /// <param name="eventName" type="String">The name of the hub event to register the callback for.</param>1546 /// <param name="callback" type="Function">The callback to be invoked.</param>1547 var self = this,1548 callbackMap = self._.callbackMap;1549 // Normalize the event name to lowercase1550 eventName = eventName.toLowerCase();1551 // If there is not an event registered for this callback yet we want to create its event space in the callback map.1552 if (!callbackMap[eventName]) {1553 callbackMap[eventName] = {};1554 }1555 // Map the callback to our encompassed function1556 callbackMap[eventName][callback] = function (e, data) {1557 callback.apply(self, data);1558 };1559 $(self).bind(makeEventName(eventName), callbackMap[eventName][callback]);1560 return self;1561 },1562 off: function (eventName, callback) {1563 /// <summary>Removes the callback invocation request from the server hub for the given event name.</summary>1564 /// <param name="eventName" type="String">The name of the hub event to unregister the callback for.</param>1565 /// <param name="callback" type="Function">The callback to be invoked.</param>1566 var self = this,1567 callbackMap = self._.callbackMap,1568 callbackSpace;1569 // Normalize the event name to lowercase1570 eventName = eventName.toLowerCase();1571 callbackSpace = callbackMap[eventName];1572 // Verify that there is an event space to unbind1573 if (callbackSpace) {1574 // Only unbind if there's an event bound with eventName and a callback with the specified callback1575 if (callbackSpace[callback]) {1576 $(self).unbind(makeEventName(eventName), callbackSpace[callback]);1577 // Remove the callback from the callback map1578 delete callbackSpace[callback];1579 // Check if there are any members left on the event, if not we need to destroy it.1580 if (!hasMembers(callbackSpace)) {1581 delete callbackMap[eventName];1582 }1583 }1584 else if (!callback) { // Check if we're removing the whole event and we didn't error because of an invalid callback1585 $(self).unbind(makeEventName(eventName));1586 delete callbackMap[eventName];1587 }1588 }1589 return self;1590 },1591 invoke: function (methodName) {1592 /// <summary>Invokes a server hub method with the given arguments.</summary>1593 /// <param name="methodName" type="String">The name of the server hub method.</param>1594 var self = this,1595 args = $.makeArray(arguments).slice(1),1596 argValues = map(args, getArgValue),1597 data = { H: self.hubName, M: methodName, A: argValues, I: callbackId },1598 d = $.Deferred(),1599 callback = function (minResult) {1600 var result = self._maximizeHubResponse(minResult);1601 // Update the hub state1602 $.extend(self.state, result.State);1603 if (result.Error) {1604 // Server hub method threw an exception, log it & reject the deferred1605 if (result.StackTrace) {1606 self.connection.log(result.Error + "\n" + result.StackTrace);1607 }1608 d.rejectWith(self, [result.Error]);1609 } else {1610 // Server invocation succeeded, resolve the deferred1611 d.resolveWith(self, [result.Result]);1612 }1613 };1614 callbacks[callbackId.toString()] = { scope: self, method: callback };1615 callbackId += 1;1616 if (!$.isEmptyObject(self.state)) {1617 data.S = self.state;1618 }1619 1620 self.connection.send(window.JSON.stringify(data));1621 return d.promise();1622 },1623 _maximizeHubResponse: function (minHubResponse) {1624 return {1625 State: minHubResponse.S,1626 Result: minHubResponse.R,1627 Id: minHubResponse.I,1628 Error: minHubResponse.E,1629 StackTrace: minHubResponse.T1630 };1631 }1632 };1633 hubProxy.fn.init.prototype = hubProxy.fn;1634 // hubConnection1635 function hubConnection(url, options) {1636 /// <summary>Creates a new hub connection.</summary>1637 /// <param name="url" type="String">[Optional] The hub route url, defaults to "/signalr".</param>1638 /// <param name="options" type="Object">[Optional] Settings to use when creating the hubConnection.</param>1639 var settings = {1640 qs: null,1641 logging: false,1642 useDefaultPath: true1643 };1644 $.extend(settings, options);1645 if (!url || settings.useDefaultPath) {1646 url = (url || "") + "/signalr";1647 }1648 return new hubConnection.fn.init(url, settings);1649 }...
RTCMultiConnection.js
Source:RTCMultiConnection.js
...139 } else {140 throw 'SocketConnection.js seems missed.';141 }142 }143 new SocketConnection(connection, function(s) {144 if (connectCallback) {145 connectCallback(connection.socket);146 }147 });148 }149 // 1st paramter is roomid150 // 2rd paramter is a callback function151 connection.openOrJoin = function(roomid, callback) {152 callback = callback || function() {};153 connection.checkPresence(roomid, function(isRoomExist, roomid) {154 if (isRoomExist) {155 connection.sessionid = roomid;156 var localPeerSdpConstraints = false;157 var remotePeerSdpConstraints = false;...
jquery.signalR-0.5.3.js
Source:jquery.signalR-0.5.3.js
...1185 }1186 };1187 hubProxy.fn.init.prototype = hubProxy.fn;1188 // hubConnection1189 function hubConnection(url) {1190 /// <summary>Creates a new hub connection.</summary>1191 /// <param name="url" type="String">[Optional] The hub route url, defaults to "/signalr"</param>1192 if (!url) {1193 url = "/signalr";1194 }1195 return new hubConnection.fn.init(url);1196 }1197 hubConnection.fn = hubConnection.prototype = $.connection();1198 hubConnection.fn.init = function (url, qs, logging) {1199 var connection = this;1200 // Call the base constructor1201 $.signalR.fn.init.call(connection, url, qs, logging);1202 // Object to store hub proxies for this connection1203 connection.proxies = {};...
jquery.signalR-0.5.2.js
Source:jquery.signalR-0.5.2.js
1/*!2* SignalR JavaScript Library v0.5.23* http://signalr.net/4*5* Copyright David Fowler and Damian Edwards 20126* Licensed under the MIT.7* https://github.com/SignalR/SignalR/blob/master/LICENSE.md8*/9/// <reference path="jquery-1.6.2.js" />10(function ($, window) {11 /// <param name="$" type="jQuery" />12 "use strict";13 if (typeof ($) !== "function") {14 // no jQuery!15 throw "SignalR: jQuery not found. Please ensure jQuery is referenced before the SignalR.js file.";16 }17 if (!window.JSON) {18 // no JSON!19 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.";20 }21 var signalR,22 _connection,23 events = {24 onStart: "onStart",25 onStarting: "onStarting",26 onSending: "onSending",27 onReceived: "onReceived",28 onError: "onError",29 onReconnect: "onReconnect",30 onStateChanged: "onStateChanged",31 onDisconnect: "onDisconnect"32 },33 log = function (msg, logging) {34 if (logging === false) {35 return;36 }37 var m;38 if (typeof (window.console) === "undefined") {39 return;40 }41 m = "[" + new Date().toTimeString() + "] SignalR: " + msg;42 if (window.console.debug) {43 window.console.debug(m);44 } else if (window.console.log) {45 window.console.log(m);46 }47 },48 isCrossDomain = function (url) {49 var link;50 url = $.trim(url);51 if (url.indexOf("http") !== 0) {52 return false;53 }54 // Create an anchor tag.55 link = window.document.createElement("a");56 link.href = url;57 return link.protocol + link.host !== window.location.protocol + window.location.host;58 },59 changeState = function (connection, expectedState, newState) {60 if (expectedState === connection.state) {61 // REVIEW: Should event fire before or after the state change actually occurs?62 $(connection).trigger(events.onStateChanged, [{ oldState: connection.state, newState: newState }]);63 connection.state = newState;64 return true;65 }66 return false;67 },68 isDisconnecting = function (connection) {69 return connection.state === signalR.connectionState.disconnected;70 };71 signalR = function (url, qs, logging) {72 /// <summary>Creates a new SignalR connection for the given url</summary>73 /// <param name="url" type="String">The URL of the long polling endpoint</param>74 /// <param name="qs" type="Object">75 /// [Optional] Custom querystring parameters to add to the connection URL.76 /// If an object, every non-function member will be added to the querystring.77 /// If a string, it's added to the QS as specified.78 /// </param>79 /// <param name="logging" type="Boolean">80 /// [Optional] A flag indicating whether connection logging is enabled to the browser81 /// console/log. Defaults to false.82 /// </param>83 /// <returns type="signalR" />84 return new signalR.fn.init(url, qs, logging);85 };86 signalR.connectionState = {87 connecting: 0,88 connected: 1,89 reconnecting: 2,90 disconnected: 491 };92 signalR.fn = signalR.prototype = {93 init: function (url, qs, logging) {94 this.url = url;95 this.qs = qs;96 if (typeof (logging) === "boolean") {97 this.logging = logging;98 }99 },100 ajaxDataType: "json",101 logging: false,102 state: signalR.connectionState.disconnected,103 reconnectDelay: 2000,104 start: function (options, callback) {105 /// <summary>Starts the connection</summary>106 /// <param name="options" type="Object">Options map</param>107 /// <param name="callback" type="Function">A callback function to execute when the connection has started</param>108 var connection = this,109 config = {110 transport: "auto",111 jsonp: false112 },113 initialize,114 deferred = $.Deferred(),115 parser = window.document.createElement("a");116 if (changeState(connection,117 signalR.connectionState.disconnected,118 signalR.connectionState.connecting) === false) {119 // Already started, just return120 deferred.resolve(connection);121 return deferred.promise();122 }123 if ($.type(options) === "function") {124 // Support calling with single callback parameter125 callback = options;126 } else if ($.type(options) === "object") {127 $.extend(config, options);128 if ($.type(config.callback) === "function") {129 callback = config.callback;130 }131 }132 // Resolve the full url133 parser.href = connection.url;134 if (!parser.protocol || parser.protocol === ":") {135 connection.protocol = window.document.location.protocol;136 connection.host = window.document.location.host;137 connection.baseUrl = connection.protocol + "//" + connection.host;138 }139 else {140 connection.protocol = parser.protocol;141 connection.host = parser.host;142 connection.baseUrl = parser.protocol + "//" + parser.host;143 }144 // Set the websocket protocol145 connection.wsProtocol = connection.protocol === "https:" ? "wss://" : "ws://";146 if (isCrossDomain(connection.url)) {147 connection.log("Auto detected cross domain url.");148 if (config.transport === "auto") {149 // If you didn't say you wanted to use jsonp, determine if it's your only choice150 // i.e. if your browser doesn't supports CORS151 if (!config.jsonp) {152 config.jsonp = !$.support.cors;153 if (config.jsonp) {154 connection.log("Using jsonp because this browser doesn't support CORS");155 }156 }157 // If we're using jsonp thn just change to longpolling158 if (config.jsonp === true) {159 config.transport = "longPolling";160 }161 else {162 // Otherwise try webSockets and longPolling since SSE doesn't support CORS163 // TODO: Support XDM with foreverFrame164 config.transport = ["webSockets", "longPolling"];165 }166 }167 }168 connection.ajaxDataType = config.jsonp ? "jsonp" : "json";169 $(connection).bind(events.onStart, function (e, data) {170 if ($.type(callback) === "function") {171 callback.call(connection);172 }173 deferred.resolve(connection);174 });175 initialize = function (transports, index) {176 index = index || 0;177 if (index >= transports.length) {178 if (!connection.transport) {179 // No transport initialized successfully180 deferred.reject("SignalR: No transport could be initialized successfully. Try specifying a different transport or none at all for auto initialization.");181 }182 return;183 }184 var transportName = transports[index],185 transport = $.type(transportName) === "object" ? transportName : signalR.transports[transportName];186 transport.start(connection, function () { // success187 connection.transport = transport;188 changeState(connection,189 signalR.connectionState.connecting,190 signalR.connectionState.connected);191 $(connection).trigger(events.onStart);192 $(window).unload(function () { // failure193 connection.stop(false /* async */);194 });195 }, function () {196 initialize(transports, index + 1);197 });198 };199 window.setTimeout(function () {200 var url = connection.url + "/negotiate";201 connection.log("Negotiating with '" + url + "'.");202 $.ajax({203 url: url,204 global: false,205 cache: false,206 type: "GET",207 data: {},208 dataType: connection.ajaxDataType,209 error: function (error) {210 $(connection).trigger(events.onError, [error.responseText]);211 deferred.reject("SignalR: Error during negotiation request: " + error.responseText);212 // Stop the connection if negotiate failed213 connection.stop();214 },215 success: function (res) {216 connection.appRelativeUrl = res.Url;217 connection.id = res.ConnectionId;218 connection.webSocketServerUrl = res.WebSocketServerUrl;219 if (!res.ProtocolVersion || res.ProtocolVersion !== "1.0") {220 $(connection).trigger(events.onError, "SignalR: Incompatible protocol version.");221 deferred.reject("SignalR: Incompatible protocol version.");222 return;223 }224 $(connection).trigger(events.onStarting);225 var transports = [],226 supportedTransports = [];227 $.each(signalR.transports, function (key) {228 if (key === "webSockets" && !res.TryWebSockets) {229 // Server said don't even try WebSockets, but keep processing the loop230 return true;231 }232 supportedTransports.push(key);233 });234 if ($.isArray(config.transport)) {235 // ordered list provided236 $.each(config.transport, function () {237 var transport = this;238 if ($.type(transport) === "object" || ($.type(transport) === "string" && $.inArray("" + transport, supportedTransports) >= 0)) {239 transports.push($.type(transport) === "string" ? "" + transport : transport);240 }241 });242 } else if ($.type(config.transport) === "object" ||243 $.inArray(config.transport, supportedTransports) >= 0) {244 // specific transport provided, as object or a named transport, e.g. "longPolling"245 transports.push(config.transport);246 } else { // default "auto"247 transports = supportedTransports;248 }249 initialize(transports);250 }251 });252 }, 0);253 return deferred.promise();254 },255 starting: function (callback) {256 /// <summary>Adds a callback that will be invoked before the connection is started</summary>257 /// <param name="callback" type="Function">A callback function to execute when the connection is starting</param>258 /// <returns type="signalR" />259 var connection = this,260 $connection = $(connection);261 $connection.bind(events.onStarting, function (e, data) {262 callback.call(connection);263 // Unbind immediately, we don't want to call this callback again264 $connection.unbind(events.onStarting);265 });266 return connection;267 },268 send: function (data) {269 /// <summary>Sends data over the connection</summary>270 /// <param name="data" type="String">The data to send over the connection</param>271 /// <returns type="signalR" />272 var connection = this;273 if (connection.state === signalR.connectionState.disconnected) {274 // Connection hasn't been started yet275 throw "SignalR: Connection must be started before data can be sent. Call .start() before .send()";276 }277 if (connection.state === signalR.connectionState.connecting) {278 // Connection hasn't been started yet279 throw "SignalR: Connection has not been fully initialized. Use .start().done() or .start().fail() to run logic after the connection has started.";280 }281 connection.transport.send(connection, data);282 // REVIEW: Should we return deferred here?283 return connection;284 },285 sending: function (callback) {286 /// <summary>Adds a callback that will be invoked before anything is sent over the connection</summary>287 /// <param name="callback" type="Function">A callback function to execute before each time data is sent on the connection</param>288 /// <returns type="signalR" />289 var connection = this;290 $(connection).bind(events.onSending, function (e, data) {291 callback.call(connection);292 });293 return connection;294 },295 received: function (callback) {296 /// <summary>Adds a callback that will be invoked after anything is received over the connection</summary>297 /// <param name="callback" type="Function">A callback function to execute when any data is received on the connection</param>298 /// <returns type="signalR" />299 var connection = this;300 $(connection).bind(events.onReceived, function (e, data) {301 callback.call(connection, data);302 });303 return connection;304 },305 stateChanged: function (callback) {306 /// <summary>Adds a callback that will be invoked when the connection state changes</summary>307 /// <param name="callback" type="Function">A callback function to execute when the connection state changes</param>308 /// <returns type="signalR" />309 var connection = this;310 $(connection).bind(events.onStateChanged, function (e, data) {311 callback.call(connection, data);312 });313 return connection;314 },315 error: function (callback) {316 /// <summary>Adds a callback that will be invoked after an error occurs with the connection</summary>317 /// <param name="callback" type="Function">A callback function to execute when an error occurs on the connection</param>318 /// <returns type="signalR" />319 var connection = this;320 $(connection).bind(events.onError, function (e, data) {321 callback.call(connection, data);322 });323 return connection;324 },325 disconnected: function (callback) {326 /// <summary>Adds a callback that will be invoked when the client disconnects</summary>327 /// <param name="callback" type="Function">A callback function to execute when the connection is broken</param>328 /// <returns type="signalR" />329 var connection = this;330 $(connection).bind(events.onDisconnect, function (e, data) {331 callback.call(connection);332 });333 return connection;334 },335 reconnected: function (callback) {336 /// <summary>Adds a callback that will be invoked when the underlying transport reconnects</summary>337 /// <param name="callback" type="Function">A callback function to execute when the connection is restored</param>338 /// <returns type="signalR" />339 var connection = this;340 $(connection).bind(events.onReconnect, function (e, data) {341 callback.call(connection);342 });343 return connection;344 },345 stop: function (async) {346 /// <summary>Stops listening</summary>347 /// <returns type="signalR" />348 var connection = this;349 if (connection.state === signalR.connectionState.disconnected) {350 return;351 }352 try {353 if (connection.transport) {354 connection.transport.abort(connection, async);355 connection.transport.stop(connection);356 connection.transport = null;357 }358 // Trigger the disconnect event359 $(connection).trigger(events.onDisconnect);360 delete connection.messageId;361 delete connection.groups;362 }363 finally {364 changeState(connection, connection.state, signalR.connectionState.disconnected);365 }366 return connection;367 },368 log: function (msg) {369 log(msg, this.logging);370 }371 };372 signalR.fn.init.prototype = signalR.fn;373 // Transports374 var transportLogic = {375 addQs: function (url, connection) {376 if (!connection.qs) {377 return url;378 }379 if (typeof (connection.qs) === "object") {380 return url + "&" + $.param(connection.qs);381 }382 if (typeof (connection.qs) === "string") {383 return url + "&" + connection.qs;384 }385 return url + "&" + window.escape(connection.qs.toString());386 },387 getUrl: function (connection, transport, reconnecting, appendReconnectUrl) {388 /// <summary>Gets the url for making a GET based connect request</summary>389 var baseUrl = transport === "webSockets" ? "" : connection.baseUrl,390 url = baseUrl + connection.appRelativeUrl,391 qs = "transport=" + transport + "&connectionId=" + window.escape(connection.id);392 if (connection.data) {393 qs += "&connectionData=" + window.escape(connection.data);394 }395 if (!reconnecting) {396 url = url + "/connect";397 } else {398 if (appendReconnectUrl) {399 url = url + "/reconnect";400 }401 if (connection.messageId) {402 qs += "&messageId=" + connection.messageId;403 }404 if (connection.groups) {405 qs += "&groups=" + window.escape(JSON.stringify(connection.groups));406 }407 }408 url += "?" + qs;409 url = this.addQs(url, connection);410 url += "&tid=" + Math.floor(Math.random() * 11);411 return url;412 },413 ajaxSend: function (connection, data) {414 var url = connection.url + "/send" + "?transport=" + connection.transport.name + "&connectionId=" + window.escape(connection.id);415 url = this.addQs(url, connection);416 $.ajax({417 url: url,418 global: false,419 type: "POST",420 dataType: connection.ajaxDataType,421 data: {422 data: data423 },424 success: function (result) {425 if (result) {426 $(connection).trigger(events.onReceived, [result]);427 }428 },429 error: function (errData, textStatus) {430 if (textStatus === "abort" ||431 (textStatus === "parsererror" && connection.ajaxDataType === "jsonp")) {432 // The parsererror happens for sends that don't return any data, and hence433 // don't write the jsonp callback to the response. This is harder to fix on the server434 // so just hack around it on the client for now.435 return;436 }437 $(connection).trigger(events.onError, [errData]);438 }439 });440 },441 ajaxAbort: function (connection, async) {442 if (typeof (connection.transport) === "undefined") {443 return;444 }445 // Async by default unless explicitly overidden446 async = typeof async === "undefined" ? true : async;447 var url = connection.url + "/abort" + "?transport=" + connection.transport.name + "&connectionId=" + window.escape(connection.id);448 url = this.addQs(url, connection);449 $.ajax({450 url: url,451 async: async,452 timeout: 1000,453 global: false,454 type: "POST",455 dataType: connection.ajaxDataType,456 data: {}457 });458 connection.log("Fired ajax abort async = " + async);459 },460 processMessages: function (connection, data) {461 var $connection = $(connection);462 if (!data) {463 return;464 }465 if (data.Disconnect) {466 connection.log("Disconnect command received from server");467 // Disconnected by the server468 connection.stop();469 return;470 }471 if (data.Messages) {472 $.each(data.Messages, function () {473 try {474 $connection.trigger(events.onReceived, [this]);475 }476 catch (e) {477 connection.log("Error raising received " + e);478 $(connection).trigger(events.onError, [e]);479 }480 });481 }482 if (data.MessageId) {483 connection.messageId = data.MessageId;484 }485 if (data.TransportData) {486 connection.groups = data.TransportData.Groups;487 }488 },489 foreverFrame: {490 count: 0,491 connections: {}492 }493 };494 signalR.transports = {495 webSockets: {496 name: "webSockets",497 send: function (connection, data) {498 connection.socket.send(data);499 },500 start: function (connection, onSuccess, onFailed) {501 var url,502 opened = false,503 that = this,504 reconnecting = !onSuccess,505 protocol,506 $connection = $(connection);507 if (window.MozWebSocket) {508 window.WebSocket = window.MozWebSocket;509 }510 if (!window.WebSocket) {511 onFailed();512 return;513 }514 if (!connection.socket) {515 if (connection.webSocketServerUrl) {516 url = connection.webSocketServerUrl;517 }518 else {519 url = connection.wsProtocol + connection.host;520 }521 // Build the url522 $(connection).trigger(events.onSending);523 url += transportLogic.getUrl(connection, this.name, reconnecting);524 connection.log("Connecting to websocket endpoint '" + url + "'");525 connection.socket = new window.WebSocket(url);526 connection.socket.onopen = function () {527 opened = true;528 connection.log("Websocket opened");529 if (onSuccess) {530 onSuccess();531 }532 else {533 if (changeState(connection,534 signalR.connectionState.reconnecting,535 signalR.connectionState.connected) === true) {536 $connection.trigger(events.onReconnect);537 }538 }539 };540 connection.socket.onclose = function (event) {541 if (!opened) {542 if (onFailed) {543 onFailed();544 }545 else if(reconnecting) {546 that.reconnect(connection);547 }548 return;549 }550 else if (typeof event.wasClean !== "undefined" && event.wasClean === false) {551 // Ideally this would use the websocket.onerror handler (rather than checking wasClean in onclose) but552 // I found in some circumstances Chrome won't call onerror. This implementation seems to work on all browsers.553 $(connection).trigger(events.onError, [event.reason]);554 connection.log("Unclean disconnect from websocket." + event.reason);555 }556 else {557 connection.log("Websocket closed");558 }559 that.reconnect(connection);560 };561 connection.socket.onmessage = function (event) {562 var data = window.JSON.parse(event.data),563 $connection;564 if (data) {565 $connection = $(connection);566 if (data.Messages) {567 transportLogic.processMessages(connection, data);568 } else {569 $connection.trigger(events.onReceived, [data]);570 }571 }572 };573 }574 },575 reconnect: function (connection) {576 this.stop(connection);577 if (connection.state === signalR.connectionState.reconnecting ||578 changeState(connection,579 signalR.connectionState.connected,580 signalR.connectionState.reconnecting) === true) {581 connection.log("Websocket reconnecting");582 this.start(connection);583 }584 },585 stop: function (connection) {586 if (connection.socket !== null) {587 connection.log("Closing the Websocket");588 connection.socket.close();589 connection.socket = null;590 }591 },592 abort: function (connection) {593 }594 },595 serverSentEvents: {596 name: "serverSentEvents",597 timeOut: 3000,598 start: function (connection, onSuccess, onFailed) {599 var that = this,600 opened = false,601 $connection = $(connection),602 reconnecting = !onSuccess,603 url,604 connectTimeOut;605 if (connection.eventSource) {606 connection.log("The connection already has an event source. Stopping it.");607 connection.stop();608 }609 if (!window.EventSource) {610 if (onFailed) {611 connection.log("This browser doesn't support SSE.");612 onFailed();613 }614 return;615 }616 $connection.trigger(events.onSending);617 url = transportLogic.getUrl(connection, this.name, reconnecting);618 try {619 connection.log("Attempting to connect to SSE endpoint '" + url + "'");620 connection.eventSource = new window.EventSource(url);621 }622 catch (e) {623 connection.log("EventSource failed trying to connect with error " + e.Message);624 if (onFailed) {625 // The connection failed, call the failed callback626 onFailed();627 }628 else {629 $connection.trigger(events.onError, [e]);630 if (reconnecting) {631 // If we were reconnecting, rather than doing initial connect, then try reconnect again632 that.reconnect(connection);633 }634 }635 return;636 }637 // After connecting, if after the specified timeout there's no response stop the connection638 // and raise on failed639 connectTimeOut = window.setTimeout(function () {640 if (opened === false) {641 connection.log("EventSource timed out trying to connect");642 connection.log("EventSource readyState: " + connection.eventSource.readyState);643 if (!reconnecting) {644 that.stop(connection);645 }646 if (reconnecting) {647 // If we're reconnecting and the event source is attempting to connect,648 // don't keep retrying. This causes duplicate connections to spawn.649 if (connection.eventSource.readyState !== window.EventSource.CONNECTING &&650 connection.eventSource.readyState !== window.EventSource.OPEN) {651 // If we were reconnecting, rather than doing initial connect, then try reconnect again652 that.reconnect(connection);653 }654 } else if (onFailed) {655 onFailed();656 }657 }658 },659 that.timeOut);660 connection.eventSource.addEventListener("open", function (e) {661 connection.log("EventSource connected");662 if (connectTimeOut) {663 window.clearTimeout(connectTimeOut);664 }665 if (opened === false) {666 opened = true;667 if (onSuccess) {668 onSuccess();669 }670 if (reconnecting) {671 if (changeState(connection,672 signalR.connectionState.reconnecting,673 signalR.connectionState.connected) === true) {674 $connection.trigger(events.onReconnect);675 }676 }677 }678 }, false);679 connection.eventSource.addEventListener("message", function (e) {680 // process messages681 if (e.data === "initialized") {682 return;683 }684 transportLogic.processMessages(connection, window.JSON.parse(e.data));685 }, false);686 connection.eventSource.addEventListener("error", function (e) {687 if (!opened) {688 if (onFailed) {689 onFailed();690 }691 return;692 }693 connection.log("EventSource readyState: " + connection.eventSource.readyState);694 if (e.eventPhase === window.EventSource.CLOSED) {695 // We don't use the EventSource's native reconnect function as it696 // doesn't allow us to change the URL when reconnecting. We need697 // to change the URL to not include the /connect suffix, and pass698 // the last message id we received.699 connection.log("EventSource reconnecting due to the server connection ending");700 that.reconnect(connection);701 } else {702 // connection error703 connection.log("EventSource error");704 $connection.trigger(events.onError);705 }706 }, false);707 },708 reconnect: function (connection) {709 var that = this;710 window.setTimeout(function () {711 that.stop(connection);712 if (connection.state === signalR.connectionState.reconnecting ||713 changeState(connection,714 signalR.connectionState.connected,715 signalR.connectionState.reconnecting) === true) {716 connection.log("EventSource reconnecting");717 that.start(connection);718 }719 }, connection.reconnectDelay);720 },721 send: function (connection, data) {722 transportLogic.ajaxSend(connection, data);723 },724 stop: function (connection) {725 if (connection && connection.eventSource) {726 connection.log("EventSource calling close()");727 connection.eventSource.close();728 connection.eventSource = null;729 delete connection.eventSource;730 }731 },732 abort: function (connection, async) {733 transportLogic.ajaxAbort(connection, async);734 }735 },736 foreverFrame: {737 name: "foreverFrame",738 timeOut: 3000,739 start: function (connection, onSuccess, onFailed) {740 var that = this,741 frameId = (transportLogic.foreverFrame.count += 1),742 url,743 connectTimeOut,744 frame = $("<iframe data-signalr-connection-id='" + connection.id + "' style='position:absolute;top:0;left:0;width:0;height:0;visibility:hidden;'></iframe>");745 if (window.EventSource) {746 // If the browser supports SSE, don't use Forever Frame747 if (onFailed) {748 connection.log("This brower supports SSE, skipping Forever Frame.");749 onFailed();750 }751 return;752 }753 $(connection).trigger(events.onSending);754 // Build the url755 url = transportLogic.getUrl(connection, this.name);756 url += "&frameId=" + frameId;757 frame.prop("src", url);758 transportLogic.foreverFrame.connections[frameId] = connection;759 connection.log("Binding to iframe's readystatechange event.");760 frame.bind("readystatechange", function () {761 if ($.inArray(this.readyState, ["loaded", "complete"]) >= 0) {762 connection.log("Forever frame iframe readyState changed to " + this.readyState + ", reconnecting");763 that.reconnect(connection);764 }765 });766 connection.frame = frame[0];767 connection.frameId = frameId;768 if (onSuccess) {769 connection.onSuccess = onSuccess;770 }771 $("body").append(frame);772 // After connecting, if after the specified timeout there's no response stop the connection773 // and raise on failed774 // REVIEW: Why is connectTimeOut set here and never used again?775 connectTimeOut = window.setTimeout(function () {776 if (connection.onSuccess) {777 connection.log("Failed to connect using forever frame source, it timed out after " + that.timeOut + "ms.");778 that.stop(connection);779 if (onFailed) {780 onFailed();781 }782 }783 }, that.timeOut);784 },785 reconnect: function (connection) {786 var that = this;787 window.setTimeout(function () {788 if (!connection.frame) {789 return;790 }791 if (connection.state === signalR.connectionState.reconnecting ||792 changeState(connection,793 signalR.connectionState.connected,794 signalR.connectionState.reconnecting) === true) {795 var frame = connection.frame,796 src = transportLogic.getUrl(connection, that.name, true) + "&frameId=" + connection.frameId;797 connection.log("Upating iframe src to '" + src + "'.");798 frame.src = src;799 }800 }, connection.reconnectDelay);801 },802 send: function (connection, data) {803 transportLogic.ajaxSend(connection, data);804 },805 receive: function (connection, data) {806 var cw;807 transportLogic.processMessages(connection, data);808 // Delete the script & div elements809 connection.frameMessageCount = (connection.frameMessageCount || 0) + 1;810 if (connection.frameMessageCount > 50) {811 connection.frameMessageCount = 0;812 cw = connection.frame.contentWindow || connection.frame.contentDocument;813 if (cw && cw.document) {814 $("body", cw.document).empty();815 }816 }817 },818 stop: function (connection) {819 var cw = null;820 if (connection.frame) {821 if (connection.frame.stop) {822 connection.frame.stop();823 } else {824 cw = connection.frame.contentWindow || connection.frame.contentDocument;825 if (cw.document && cw.document.execCommand) {826 cw.document.execCommand("Stop");827 }828 }829 $(connection.frame).remove();830 delete transportLogic.foreverFrame.connections[connection.frameId];831 connection.frame = null;832 connection.frameId = null;833 delete connection.frame;834 delete connection.frameId;835 connection.log("Stopping forever frame");836 }837 },838 abort: function (connection, async) {839 transportLogic.ajaxAbort(connection, async);840 },841 getConnection: function (id) {842 return transportLogic.foreverFrame.connections[id];843 },844 started: function (connection) {845 if (connection.onSuccess) {846 connection.onSuccess();847 connection.onSuccess = null;848 delete connection.onSuccess;849 }850 else {851 if (changeState(connection,852 signalR.connectionState.reconnecting,853 signalR.connectionState.connected) === true) {854 // If there's no onSuccess handler we assume this is a reconnect855 $(connection).trigger(events.onReconnect);856 }857 }858 }859 },860 longPolling: {861 name: "longPolling",862 reconnectDelay: 3000,863 start: function (connection, onSuccess, onFailed) {864 /// <summary>Starts the long polling connection</summary>865 /// <param name="connection" type="signalR">The SignalR connection to start</param>866 var that = this,867 initialConnectFired = false;868 if (connection.pollXhr) {869 connection.log("Polling xhr requests already exists, aborting.");870 connection.stop();871 }872 connection.messageId = null;873 window.setTimeout(function () {874 (function poll(instance, raiseReconnect) {875 $(instance).trigger(events.onSending);876 var messageId = instance.messageId,877 connect = (messageId === null),878 reconnecting = !connect,879 url = transportLogic.getUrl(instance, that.name, reconnecting, raiseReconnect),880 reconnectTimeOut = null,881 reconnectFired = false;882 if (reconnecting === true && raiseReconnect === true) {883 if (connection.state !== signalR.connectionState.reconnecting &&884 changeState(connection,885 signalR.connectionState.connected,886 signalR.connectionState.reconnecting) === false) {887 return;888 }889 }890 connection.log("Attempting to connect to '" + url + "' using longPolling.");891 instance.pollXhr = $.ajax({892 url: url,893 global: false,894 type: "GET",895 dataType: connection.ajaxDataType,896 success: function (data) {897 var delay = 0,898 timedOutReceived = false;899 if (initialConnectFired == false) {900 onSuccess();901 initialConnectFired = true;902 }903 if (raiseReconnect === true) {904 // Fire the reconnect event if it hasn't been fired as yet905 if (reconnectFired === false) {906 connection.log("Raising the reconnect event");907 if (changeState(connection,908 signalR.connectionState.reconnecting,909 signalR.connectionState.connected) === true) {910 $(instance).trigger(events.onReconnect);911 reconnectFired = true;912 }913 }914 }915 transportLogic.processMessages(instance, data);916 if (data &&917 data.TransportData &&918 $.type(data.TransportData.LongPollDelay) === "number") {919 delay = data.TransportData.LongPollDelay;920 }921 if (data && data.TimedOut) {922 timedOutReceived = data.TimedOut;923 }924 if (data && data.Disconnect) {925 return;926 }927 if (isDisconnecting(instance) === true) {928 return;929 }930 if (delay > 0) {931 window.setTimeout(function () {932 poll(instance, timedOutReceived);933 }, delay);934 } else {935 poll(instance, timedOutReceived);936 }937 },938 error: function (data, textStatus) {939 if (textStatus === "abort") {940 connection.log("Aborted xhr requst.");941 return;942 }943 connection.log("An error occurred using longPolling. Status = " + textStatus + ". " + data.responseText);944 if (reconnectTimeOut) {945 // If the request failed then we clear the timeout so that the946 // reconnect event doesn't get fired947 clearTimeout(reconnectTimeOut);948 }949 $(instance).trigger(events.onError, [data.responseText]);950 window.setTimeout(function () {951 if (isDisconnecting(instance) === false) {952 poll(instance, true);953 }954 }, connection.reconnectDelay);955 }956 });957 if (raiseReconnect === true) {958 reconnectTimeOut = window.setTimeout(function () {959 if (reconnectFired === false) {960 if (changeState(connection,961 signalR.connectionState.reconnecting,962 signalR.connectionState.connected) === true) {963 $(instance).trigger(events.onReconnect);964 reconnectFired = true;965 }966 }967 },968 that.reconnectDelay);969 }970 } (connection));971 // Now connected972 // There's no good way know when the long poll has actually started so973 // we assume it only takes around 150ms (max) to start the connection974 window.setTimeout(function () {975 if (initialConnectFired === false) {976 onSuccess();977 initialConnectFired = true;978 }979 }, 150);980 }, 250); // Have to delay initial poll so Chrome doesn't show loader spinner in tab981 },982 send: function (connection, data) {983 transportLogic.ajaxSend(connection, data);984 },985 stop: function (connection) {986 /// <summary>Stops the long polling connection</summary>987 /// <param name="connection" type="signalR">The SignalR connection to stop</param>988 if (connection.pollXhr) {989 connection.pollXhr.abort();990 connection.pollXhr = null;991 delete connection.pollXhr;992 }993 },994 abort: function (connection, async) {995 transportLogic.ajaxAbort(connection, async);996 }997 }998 };999 signalR.noConflict = function () {1000 /// <summary>Reinstates the original value of $.connection and returns the signalR object for manual assignment</summary>1001 /// <returns type="signalR" />1002 if ($.connection === signalR) {1003 $.connection = _connection;1004 }1005 return signalR;1006 };1007 if ($.connection) {1008 _connection = $.connection;1009 }1010 $.connection = $.signalR = signalR;...
voltdb.service.js
Source:voltdb.service.js
...17 try {18 var serverName = lServerName != null ? lServerName : server;19 var portId = lPort != null ? lPort : port;2021 VoltDBCore.TestConnection(serverName, portId, lAdmin, lUsername, lPassword, isHashedPassword, "DATABASE_LOGIN", function (result, response) {22 onConnectionAdded(result, response);23 }, isLoginTest);2425 } catch (e) {26 console.log(e.message);27 }28 };2930 this.CheckServerConnection = function (checkConnection) {31 try {32 VoltDBCore.CheckServerConnection(server, port, admin, user, password, isHashedPassword, "DATABASE_LOGIN", checkConnection);33 } catch (e) {34 console.log(e.message);35 }36 };3738 this.SetUserCredentials = function (lUsername, lPassword, lAdmin) {39 user = lUsername;40 password = lPassword;41 admin = lAdmin;42 };4344 // build Authorization header based on scheme you could flip to diff header. Server understands both.45 this.BuildAuthorization = function(user, isHashedPassword, password) {46 var authz = null;47 if (user != null && isHashedPassword != null) {48 authz = "Hashed " + user + ":" + isHashedPassword;49 } else if (user != null && password != null) {50 var up = user + ":" + password;51 authz = "Basic " + $().crypt({method: "b64enc", source: up});52 }53 return authz;54 }5556 this.ChangeServerConfiguration = function (serverName, portId, userName, pw, isHashPw, isAdmin) {57 server = serverName != null ? serverName : server;58 port = portId != null ? portId : port;59 user = userName != undefined ? userName : "";60 password = pw != undefined ? pw : "";61 isHashedPassword = isHashPw;62 admin = isAdmin != undefined ? isAdmin : true;6364 };6566 this.GetSystemInformation = function (onConnectionAdded) {67 try {68 var processName = "SYSTEM_INFORMATION";69 var procedureNames = ['@SystemInformation', '@Statistics'];70 var parameters = ["OVERVIEW", "MEMORY"];71 var values = [undefined, '0'];72 _connection = VoltDBCore.HasConnection(server, port, admin, user, processName);73 if (_connection == null) {74 VoltDBCore.TestConnection(server, port, admin, user, password, isHashedPassword, processName, function (result) {75 if (result == true) {76 updateTips("Connection successful.");7778 VoltDBCore.AddConnection(server, port, admin, user, password, isHashedPassword, procedureNames, parameters, values, processName, function (connection, status) {79 onConnectionAdded(connection, status);80 });81 } else updateTips("Unable to connect.");8283 });8485 } else {86 VoltDBCore.updateConnection(server, port, admin, user, password, isHashedPassword, procedureNames, parameters, values, processName, _connection, function (connection, status) {87 onConnectionAdded(connection, status);8889 });9091 }92 } catch (e) {93 console.log(e.message);94 }9596 function updateTips(t) {97 tips98 .text(t)99 .addClass("ui-state-highlight");100 setTimeout(function () {101 tips.removeClass("ui-state-highlight", 1500);102 }, 500);103 }104105106 };107108 this.GetClusterInformation = function (onConnectionAdded) {109 try {110 var processName = "CLUSTER_INFORMATION";111 var procedureNames = ['@SystemInformation'];112 var parameters = ["OVERVIEW"];113 var values = [undefined];114 _connection = VoltDBCore.HasConnection(server, port, admin, user, processName);115 if (_connection == null) {116 VoltDBCore.TestConnection(server, port, admin, user, password, isHashedPassword, processName, function (result) {117 if (result == true) {118 VoltDBCore.AddConnection(server, port, admin, user, password, isHashedPassword, procedureNames, parameters, values, processName, function (connection, status) {119 onConnectionAdded(connection, status);120 });121 } 122 });123124 } else {125 VoltDBCore.updateConnection(server, port, admin, user, password, isHashedPassword, procedureNames, parameters, values, processName, _connection, function (connection, status) {126 onConnectionAdded(connection, status);127128 });129130 }131 } catch (e) {132 console.log(e.message);133 }134 };135136 this.GetSystemInformationDeployment = function (onConnectionAdded) {137 try {138 var processName = "SYSTEM_INFORMATION_DEPLOYMENT";139 var procedureNames = ['@SystemInformation'];140 var parameters = ["DEPLOYMENT"];141 var values = [];142 _connection = VoltDBCore.HasConnection(server, port, admin, user, processName);143 if (_connection == null) {144 VoltDBCore.TestConnection(server, port, admin, user, password, isHashedPassword, processName, function (result) {145 if (result == true) {146 updateTips("Connection successful.");147148 VoltDBCore.AddConnection(server, port, admin, user, password, isHashedPassword, procedureNames, parameters, values, processName, function (connection, status) {149 onConnectionAdded(connection);150 });151 } else updateTips("Unable to connect.");152153 });154155 } else {156 VoltDBCore.updateConnection(server, port, admin, user, password, isHashedPassword, procedureNames, parameters, values, processName, _connection, function (connection, status) {157 onConnectionAdded(connection);158159 });160161 }162 } catch (e) {163 console.log(e.message);164 }165166 function updateTips(t) {167 tips168 .text(t)169 .addClass("ui-state-highlight");170 setTimeout(function () {171 tips.removeClass("ui-state-highlight", 1500);172 }, 500);173 }174175176 };177178 this.GetDataTablesInformation = function (onConnectionAdded) {179 try {180 var processName = "DATABASE_INFORMATION";181 var procedureNames = ['@Statistics', '@SystemCatalog', '@SystemCatalog'];182 var parameters = ["TABLE", "TABLES"];183 var values = ['0', undefined];184 _connection = VoltDBCore.HasConnection(server, port, admin, user, processName);185 if (_connection == null) {186 VoltDBCore.TestConnection(server, port, admin, user, password, isHashedPassword, processName, function (result) {187 if (result == true) {188 VoltDBCore.AddConnection(server, port, admin, user, password, isHashedPassword, procedureNames, parameters, values, processName, function (connection, status) {189 onConnectionAdded(connection, status);190 });191 }192193 });194195 } else {196 VoltDBCore.updateConnection(server, port, admin, user, password, isHashedPassword, procedureNames, parameters, values, processName, _connection, function (connection, status) {197 onConnectionAdded(connection, status);198199 });200201 }202203 } catch (e) {204 console.log(e.message);205 }206207 };208209 this.GetProceduresInformation = function (onConnectionAdded) {210 try {211 var processName = "DATABASE_INFORMATION";212 var procedureNames = ['@Statistics'];213 var parameters = ["PROCEDUREPROFILE"];214 var values = ['0'];215 _connection = VoltDBCore.HasConnection(server, port, admin, user, processName);216 if (_connection == null) {217 VoltDBCore.TestConnection(server, port, admin, user, password, isHashedPassword, processName, function (result) {218 if (result == true) {219 VoltDBCore.AddConnection(server, port, admin, user, password, isHashedPassword, procedureNames, parameters, values, processName, function (connection, status) {220 onConnectionAdded(connection, status);221 });222 }223224 });225226 } else {227 VoltDBCore.updateConnection(server, port, admin, user, password, isHashedPassword, procedureNames, parameters, values, processName, _connection, function (connection, status) {228 onConnectionAdded(connection, status);229230 });231232 }233234 } catch (e) {235 console.log(e.message);236 }237238 };239240 this.getProcedureContextForSorting = function () {241 try {242 var processName = "DATABASE_INFORMATION";243 var procedureNames = ['@Statistics'];244 var parameters = ["PROCEDUREPROFILE"];245 var values = ['0'];246 var lconnection = VoltDBCore.HasConnection(server, port, admin, user, processName);247 if (lconnection == null) {248 VoltDBCore.TestConnection(server, port, admin, user, password, isHashedPassword, processName, function (result) {249 if (result == true) {250 VoltDBCore.AddConnection(server, port, admin, user, password, isHashedPassword, procedureNames, parameters, values, processName, function (connection, status) {251 lconnection = connection;252 });253 }254255 });256 }257 return lconnection;258259 } catch (e) {260 console.log(e.message);261 }262 };263264 this.getTablesContextForSorting = function () {265 try {266 var processName = "DATABASE_INFORMATION";267 var procedureNames = ['@Statistics'];268 var parameters = ["TABLE"];269 var values = ['0'];270 var lconnection = VoltDBCore.HasConnection(server, port, admin, user, processName);271 if (lconnection == null) {272 VoltDBCore.TestConnection(server, port, admin, user, password, isHashedPassword, processName, function (result) {273 if (result == true) {274 VoltDBCore.AddConnection(server, port, admin, user, password, isHashedPassword, procedureNames, parameters, values, processName, function (connection, status) {275 lconnection = connection;276 });277 }278279 });280 } //else {281 // VoltDBCore.updateConnection(server, port, admin, user, password, isHashedPassword, procedureNames, parameters, values, processName, lconnection, function (connection, status) {282 // lconnection = connection;283 // });284285 //}286 return lconnection;287288289 } catch (e) {290 console.log(e.message);291 }292 };293294 this.GetMemoryInformation = function (onConnectionAdded) {295 try {296 var processName = "GRAPH_MEMORY";297 var procedureNames = ['@Statistics'];298 var parameters = ["MEMORY"];299 var values = ['0'];300 _connection = VoltDBCore.HasConnection(server, port, admin, user, processName);301 if (_connection == null) {302 VoltDBCore.TestConnection(server, port, admin, user, password, isHashedPassword, processName, function (result) {303 if (result == true) {304 VoltDBCore.AddConnection(server, port, admin, user, password, isHashedPassword, procedureNames, parameters, values, processName, function (connection, status) {305 onConnectionAdded(connection, status);306 });307 }308309 });310311 } else {312 VoltDBCore.updateConnection(server, port, admin, user, password, isHashedPassword, procedureNames, parameters, values, processName, _connection, function (connection, status) {313 onConnectionAdded(connection, status);314315 });316317 }318319 } catch (e) {320 console.log(e.message);321 }322323 };324325 this.GetGraphLatencyInformation = function (onConnectionAdded) {326 try {327 var processName = "GRAPH_LATENCY";328 var procedureNames = ['@Statistics'];329 var parameters = ["LATENCY_HISTOGRAM"];330 var values = ['0'];331 _connection = VoltDBCore.HasConnection(server, port, admin, user, processName);332 if (_connection == null) {333 VoltDBCore.TestConnection(server, port, admin, user, password, isHashedPassword, processName, function (result) {334 if (result == true) {335 VoltDBCore.AddConnection(server, port, admin, user, password, isHashedPassword, procedureNames, parameters, values, processName, function (connection, status) {336 onConnectionAdded(connection, status);337 });338 }339340 });341342 } else {343 VoltDBCore.updateConnection(server, port, admin, user, password, isHashedPassword, procedureNames, parameters, values, processName, _connection, function (connection, status) {344 onConnectionAdded(connection, status);345346 });347348 }349350 } catch (e) {351 console.log(e.message);352 }353354 };355356 this.GetCPUInformation = function (onConnectionAdded) {357 try {358 //GRAPH_CPU359 var processName = "GRAPH_CPU";360 var procedureNames = ['@Statistics'];361 var parameters = ["CPU"];362 var values = ['0'];363 _connection = VoltDBCore.HasConnection(server, port, admin, user, processName);364 if (_connection == null) {365 VoltDBCore.TestConnection(server, port, admin, user, password, isHashedPassword, processName, function (result) {366 if (result == true) {367 VoltDBCore.AddConnection(server, port, admin, user, password, isHashedPassword, procedureNames, parameters, values, processName, function (connection, status) {368 onConnectionAdded(connection, status);369 });370 }371372 });373374 } else {375 VoltDBCore.updateConnection(server, port, admin, user, password, isHashedPassword, procedureNames, parameters, values, processName, _connection, function (connection, status) {376 onConnectionAdded(connection, status);377378 });379380 }381382 } catch (e) {383 console.log(e.message);384 }385386 };387 388 //Render Cluster Transaction Graph389 this.GetTransactionInformation = function (onConnectionAdded) {390 try {391 var processName = "GRAPH_TRANSACTION";392 var procedureNames = ['@Statistics'];393 var parameters = ["PROCEDUREPROFILE"];394 var values = ['0'];395 _connection = VoltDBCore.HasConnection(server, port, admin, user, processName);396 if (_connection == null) {397 VoltDBCore.TestConnection(server, port, admin, user, password, isHashedPassword, processName, function (result) {398 if (result == true) {399 VoltDBCore.AddConnection(server, port, admin, user, password, isHashedPassword, procedureNames, parameters, values, processName, function (connection, status) {400 onConnectionAdded(connection, status);401 });402 }403404 });405406 } else {407 VoltDBCore.updateConnection(server, port, admin, user, password, isHashedPassword, procedureNames, parameters, values, processName, _connection, function (connection, status) {408 onConnectionAdded(connection, status);409410 });411412 }413414 } catch (e) {415 console.log(e.message);416 }417418 };419420 this.GetTableInformation = function (onConnectionAdded) {421 try {422 var processName = "TABLE_INFORMATION";423 var procedureNames = ['@Statistics', '@Statistics', '@SystemCatalog', '@SystemCatalog', '@SystemCatalog'];424 var parameters = ["TABLE", "INDEX", "COLUMNS", "PROCEDURES", "PROCEDURECOLUMNS"];425 var values = ['0', '0', undefined];426 var isAdmin = false;427 _connection = VoltDBCore.HasConnection(server, port, isAdmin, user, processName);428 if (_connection == null) {429 VoltDBCore.TestConnection(server, port, isAdmin, user, password, isHashedPassword, processName, function (result) {430 if (result == true) {431 VoltDBCore.AddConnection(server, port, isAdmin, user, password, isHashedPassword, procedureNames, parameters, values, processName, function (connection, status) {432 onConnectionAdded(connection, status);433 });434 }435436 });437438 } else {439 VoltDBCore.updateConnection(server, port, isAdmin, user, password, isHashedPassword, procedureNames, parameters, values, processName, _connection, function (connection, status) {440 onConnectionAdded(connection, status);441442 });443444 }445446 } catch (e) {447 console.log(e.message);448 }449450 };451452 this.GetShortApiProfile = function (onConnectionAdded) {453 try {454 var processName = "SHORTAPI_PROFILE";455 var procedureNames = [];456 var parameters = [];457 var values = [];458 var shortApiDetails = {459 isShortApiCall: true,460 apiPath: 'profile'461 };462463 _connection = VoltDBCore.HasConnection(server, port, admin, user, processName);464 if (_connection == null) {465 VoltDBCore.TestConnection(server, port, admin, user, password, isHashedPassword, processName, function (result) {466 if (result == true) {467 VoltDBCore.AddConnection(server, port, admin, user, password, isHashedPassword, procedureNames, parameters, values, processName, function (connection, status) {468 onConnectionAdded(connection, status);469 }, shortApiDetails);470 }471 });472473 } else {474 VoltDBCore.updateConnection(server, port, admin, user, password, isHashedPassword, procedureNames, parameters, values, processName, _connection, function (connection, status) {475 onConnectionAdded(connection, status);476 }, shortApiDetails);477478 }479480 } catch (e) {481 console.log(e.message);482 }483484 };485486 this.GetShortApiDeployment = function (onConnectionAdded) {487 try {488 var processName = "SHORTAPI_DEPLOYMENT";489 var procedureNames = [];490 var parameters = [];491 var values = [];492 var shortApiDetails = {493 isShortApiCall : true,494 apiPath : 'deployment'495 };496497 _connection = VoltDBCore.HasConnection(server, port, admin, user, processName);498 if (_connection == null) {499 var status = "";500 var statusString = "";501 502 VoltDBCore.TestConnection(server, port, admin, user, password, isHashedPassword, processName, function (result) {503 if (result == true) {504 VoltDBCore.AddConnection(server, port, admin, user, password, isHashedPassword, procedureNames, parameters, values, processName, function (connection, status) {505 status = connection.Metadata['@SHORTAPI_DEPLOYMENT_status'];506 statusString = connection.Metadata['@SHORTAPI_DEPLOYMENT_statusString'];507 onConnectionAdded(connection);508 509 }, shortApiDetails);510 }511 });512513 } else {514 VoltDBCore.updateConnection(server, port, admin, user, password, isHashedPassword, procedureNames, parameters, values, processName, _connection, function (connection, status) {515 status = connection.Metadata['@SHORTAPI_DEPLOYMENT_status'];516 statusString = connection.Metadata['@SHORTAPI_DEPLOYMENT_statusString'];517 onConnectionAdded(connection);518 519 }, shortApiDetails);520521 }522523 } catch (e) {524 console.log(e.message);525 }526527 };528529 //Update admin configuration530 this.UpdateAdminConfiguration = function (updatedData, onConnectionAdded) {531 try {532 var processName = "SHORTAPI_UPDATEDEPLOYMENT";533 var procedureNames = [];534 var parameters = [];535 var values = [];536 var shortApiDetails = {537 isShortApiCall: true,538 isUpdateConfiguration: true,539 apiPath: 'deployment',540 updatedData: 'deployment=' + JSON.stringify(updatedData)541 };542543 _connection = VoltDBCore.HasConnection(server, port, admin, user, processName);544 if (_connection == null) {545 VoltDBCore.TestConnection(server, port, admin, user, password, isHashedPassword, processName, function (result) {546 if (result == true) {547 VoltDBCore.AddConnection(server, port, admin, user, password, isHashedPassword, procedureNames, parameters, values, processName, function (connection, status) {548 onConnectionAdded(connection, status);549 }, shortApiDetails);550 }551 });552553 } else {554 VoltDBCore.updateConnection(server, port, admin, user, password, isHashedPassword, procedureNames, parameters, values, processName, _connection, function (connection, status) {555 onConnectionAdded(connection, status);556 }, shortApiDetails);557558 }559560 } catch (e) {561 console.log(e.message);562 }563564 };565566 //admin configuration567 this.editConfigurationItem = function (configGroup, configMember,configValue,onConnectionSucceeded) {568 try {569 var processName = "ADMIN_".concat(configGroup);570 var procedureNames = [];571 var parameters = [];572 var values = [];573 var isAdmin = true;574575 switch (configGroup) {576 case 'OVERVIEW':577 procedureNames = ['@SystemInformation'];578 parameters = [configMember];579 values = [configValue];580 break;581582 case 'PORT':583 procedureNames = ['@SystemInformation'];584 parameters = [configMember];585 values = [configValue];586 break;587588 case 'DIRECTORIES':589 procedureNames = ['@SystemInformation'];590 parameters = [configMember];591 values = [configValue];592 break;593594 }595596 _connection = VoltDBCore.HasConnection(server, port, isAdmin, user, processName);597 if (_connection == null) {598 VoltDBCore.TestConnection(server, port, isAdmin, user, password, isHashedPassword, processName, function (result) {599 if (result == true) {600 VoltDBCore.AddConnection(server, port, isAdmin, user, password, isHashedPassword, procedureNames, parameters, values, processName, function (connection, status) {601 onConnectionSucceeded(connection, status);602 });603 }604605 });606607 } else {608 VoltDBCore.updateConnection(server, port, isAdmin, user, password, isHashedPassword, procedureNames, parameters, values, processName, _connection, function (connection, status) {609 onConnectionSucceeded(connection, status);610611 });612613 }614615 }616 catch (e) {617618 }619 };620621 this.stopServerNode = function(nodeId,onConnectionAdded) {622 try {623 var processName = "SYSTEMINFORMATION_STOPSERVER";624 var procedureNames = ['@StopNode'];625 var parameters = [nodeId.toString()];626 var values = [undefined];627 var statusString = "";628629 _connection = VoltDBCore.HasConnection(server, port, admin, user, processName);630 if (_connection == null) {631 VoltDBCore.TestConnection(server, port, admin, user, password, isHashedPassword, processName, function (result) {632 if (result == true) {633 var status = 0;634 635 VoltDBCore.AddConnection(server, port, admin, user, password, isHashedPassword, procedureNames, parameters, values, processName, function(connection, status) {636 status = connection.Metadata['@StopNode_' + nodeId.toString() + '_status'];637 statusString = connection.Metadata['@StopNode_' + nodeId.toString() + '_statusString'];638 if (!(status == "" || status == undefined)) {639 onConnectionAdded(connection, status, statusString);640 }641642 });643 }644645 });646647 } else {648 VoltDBCore.updateConnection(server, port, admin, user, password, isHashedPassword, procedureNames, parameters, values, processName, _connection, function (connection, status) {649 status = connection.Metadata['@StopNode_' + nodeId.toString() + '_status'];650 statusString = connection.Metadata['@StopNode_' + nodeId.toString() + '_statusString'];651652 if (!(status == "" || status == undefined)) {653 onConnectionAdded(connection, status, statusString);654 }655656 });657658 }659660 } catch (e) {661 console.log(e.message);662 }663664 };665 666 this.PauseClusterState = function (onConnectionAdded) {667 try {668 var processName = "SYSTEMINFORMATION_PAUSECLUSTER";669 var procedureNames = ['@Pause'];670 var parameters = [undefined];671 var values = [undefined];672673 _connection = VoltDBCore.HasConnection(server, port, admin, user, processName);674 if (_connection == null) {675 VoltDBCore.TestConnection(server, port, admin, user, password, isHashedPassword, processName, function (result) {676 if (result == true) {677 var status = 0;678 VoltDBCore.AddConnection(server, port, admin, user, password, isHashedPassword, procedureNames, parameters, values, processName, function (connection, status) {679 status = connection.Metadata['@Pause_status'];680 if (!(status == "" || status == undefined)) {681 onConnectionAdded(connection, status);682 }683684685 });686 }687688 });689690 } else {691 VoltDBCore.updateConnection(server, port, admin, user, password, isHashedPassword, procedureNames, parameters, values, processName, _connection, function (connection, status) {692 status = connection.Metadata['@Pause_status'];693 if (!(status == "" || status == undefined)) {694 onConnectionAdded(connection, status);695 }696697 });698699 }700701 } catch (e) {702 console.log(e.message);703 }704705706 };707 708 this.ResumeClusterState = function (onConnectionAdded) {709 try {710 var processName = "SYSTEMINFORMATION_RESUMECLUSTER";711 var procedureNames = ['@Resume'];712 var parameters = [undefined];713 var values = [undefined];714715 _connection = VoltDBCore.HasConnection(server, port, admin, user, processName);716 if (_connection == null) {717 VoltDBCore.TestConnection(server, port, admin, user, password, isHashedPassword, processName, function (result) {718 if (result == true) {719 VoltDBCore.AddConnection(server, port, admin, user, password, isHashedPassword, procedureNames, parameters, values, processName, function (connection, status) {720 status = connection.Metadata['@Resume_status'];721 if (!(status == "" || status == undefined)) {722 onConnectionAdded(connection, status);723 }724 });725 }726727 });728729 } else {730 VoltDBCore.updateConnection(server, port, admin, user, password, isHashedPassword, procedureNames, parameters, values, processName, _connection, function (connection, status) {731 status = connection.Metadata['@Resume_status'];732 if (!(status == "" || status == undefined)) {733 onConnectionAdded(connection, status);734 }735736 });737738 }739740 } catch (e) {741 console.log(e.message);742 }743744745 };746 747 this.ShutdownClusterState = function (onConnectionAdded) {748 try {749 var processName = "SYSTEMINFORMATION_SHUTDOWNCLUSTER";750 var procedureNames = ['@Shutdown'];751 var parameters = [undefined];752 var values = [undefined];753754 _connection = VoltDBCore.HasConnection(server, port, admin, user, processName);755 if (_connection == null) {756 VoltDBCore.TestConnection(server, port, admin, user, password, isHashedPassword, processName, function (result) {757 if (result == true) {758 VoltDBCore.AddConnection(server, port, admin, user, password, isHashedPassword, procedureNames, parameters, values, processName, function (connection, status) {759 status = connection.Metadata['@Shutdown_status'];760 if (!(status == "" || status == undefined)) {761 onConnectionAdded(connection, status);762 }763 });764 }765766 });767768 } else {769 VoltDBCore.updateConnection(server, port, admin, user, password, isHashedPassword, procedureNames, parameters, values, processName, _connection, function (connection, status) {770 status = connection.Metadata['@Shutdown_status'];771 if (!(status == "" || status == undefined)) {772 onConnectionAdded(connection, status);773 }774775 });776777 }778779 } catch (e) {780 console.log(e.message);781 }782783784 };785 786 this.PromoteCluster = function (onConnectionAdded) {787 try {788 var processName = "SYSTEMINFORMATION_PROMOTECLUSTER";789 var procedureNames = ['@Promote'];790 var parameters = [undefined];791 var values = [undefined];792793 _connection = VoltDBCore.HasConnection(server, port, admin, user, processName);794 if (_connection == null) {795 VoltDBCore.TestConnection(server, port, admin, user, password, isHashedPassword, processName, function (result) {796 if (result == true) {797 VoltDBCore.AddConnection(server, port, admin, user, password, isHashedPassword, procedureNames, parameters, values, processName, function (connection, status) {798 status = connection.Metadata['@Promote_status'];799 if (!(status == "" || status == undefined)) {800 onConnectionAdded(connection, status, connection.Metadata['@Promote_statusstring']);801 }802 });803 }804805 });806807 } else {808 VoltDBCore.updateConnection(server, port, admin, user, password, isHashedPassword, procedureNames, parameters, values, processName, _connection, function (connection, status) {809 status = connection.Metadata['@Promote_status'];810 if (!(status == "" || status == undefined)) {811 onConnectionAdded(connection, status, connection.Metadata['@Promote_statusstring']);812 }813814 });815816 }817818 } catch (e) {819 console.log(e.message);820 }821822823 };824825 this.SaveSnapShot = function(snapshotDir,snapshotFileName, onConnectionAdded) {826 try {827 var processName = "SYSTEMINFORMATION_SAVESNAPSHOT";828 var procedureNames = ['@SnapshotSave'];829 var parameters = ["'" + snapshotDir + "'",snapshotFileName, 0];830 var values = [undefined];831832 _connection = VoltDBCore.HasConnection(server, port, admin, user, processName);833 if (_connection == null) {834 VoltDBCore.TestConnection(server, port, admin, user, password, isHashedPassword, processName, function (result) {835 if (result == true) {836 VoltDBCore.AddConnection(server, port, admin, user, password, isHashedPassword, procedureNames, parameters, values, processName, function (connection, status) {837 status = connection.Metadata['@SnapshotSave_status'];838 if (!(status == "" || status == undefined)) {839 onConnectionAdded(connection, status);840 }841 });842 }843844 });845846 } else {847 VoltDBCore.updateConnection(server, port, admin, user, password, isHashedPassword, procedureNames, parameters, values, processName, _connection, function (connection, status) {848 status = connection.Metadata['@SnapshotSave_status'];849 if (!(status == "" || status == undefined)) {850 onConnectionAdded(connection, status);851 }852853 });854855 }856857 } catch (e) {858 console.log(e.message);859 }860861 };862863 this.GetSnapshotList = function(snapshotDirectory, onConnectionAdded) {864 try {865 var processName = "SYSTEMINFORMATION_SCANSNAPSHOTS";866 var procedureNames = ['@SnapshotScan'];867 var parameters = [snapshotDirectory];868 var values = [undefined];869 _connection = VoltDBCore.HasConnection(server, port, admin, user, processName);870 if (_connection == null) {871 VoltDBCore.TestConnection(server, port, admin, user, password, isHashedPassword, processName, function(result) {872 if (result == true) {873 VoltDBCore.AddConnection(server, port, admin, user, password, isHashedPassword, procedureNames, parameters, values, processName, function(connection, status) {874 status = connection.Metadata['@SnapshotScan_status'];875 if (!(status == "" || status == undefined)) {876 onConnectionAdded(connection, status);877 }878 });879 }880881 });882883 } else {884 VoltDBCore.updateConnection(server, port, admin, user, password, isHashedPassword, procedureNames, parameters, values, processName, _connection, function(connection, status) {885 status = connection.Metadata['@SnapshotScan_status'];886 if (!(status == "" || status == undefined)) {887 onConnectionAdded(connection, status);888 }889890 });891892 }893894 } catch(e) {895 console.log(e.message);896 }897898 };899 900 this.RestoreSnapShot = function (snapshotDir, snapshotFileName, onConnectionAdded) {901 try {902 var processName = "SYSTEMINFORMATION_RESTORESNAPSHOT";903 var procedureNames = ['@SnapshotRestore'];904 var parameters = ["'" + snapshotDir + "'", snapshotFileName, 0];905 var values = [undefined];906907 _connection = VoltDBCore.HasConnection(server, port, admin, user, processName);908 if (_connection == null) {909 VoltDBCore.TestConnection(server, port, admin, user, password, isHashedPassword, processName, function (result) {910 if (result == true) {911 VoltDBCore.AddConnection(server, port, admin, user, password, isHashedPassword, procedureNames, parameters, values, processName, function (connection, status) {912 status = connection.Metadata['@SnapshotRestore_status'];913 if (!(status == "" || status == undefined)) {914 onConnectionAdded(connection, status, connection.Metadata['@SnapshotRestore_statusstring']);915 }916 });917 }918919 });920921 } else {922 VoltDBCore.updateConnection(server, port, admin, user, password, isHashedPassword, procedureNames, parameters, values, processName, _connection, function (connection, status) {923 status = connection.Metadata['@SnapshotRestore_status'];924 if (!(status == "" || status == undefined)) {925 onConnectionAdded(connection, status, connection.Metadata['@SnapshotRestore_statusstring']);926 }927928 });929930 }931932 } catch (e) {933 console.log(e.message);934 }935936 };
...
Using AI Code Generation
1describe('My First Test', function() {2 it('Does not do much!', function() {3 cy.contains('type').click()4 cy.url().should('include', '/commands/actions')5 cy.get('.action-email')6 .type('
Using AI Code Generation
1describe('My First Test Suite', function() 2{3it('My FirstTest case',function() {4cy.get('.search-keyword').type('ca')5cy.wait(2000)6cy.get('.products').as('productLocator')7cy.get('@productLocator').find('.product').each(($el, index, $list) => {8const vegText=$el.find('h4.product-name').text()9if(vegText.includes('Cashews'))10{11$el.find('button').click()12}13})14cy.get('.brand').should('have.text','GREENKART')15cy.get('.brand').then(function(logoelement)16{17cy.log(logoelement.text())18})19})20})
Using AI Code Generation
1describe("My First Test Suite", function() {2 it("My FirstTest case", function() {3 cy.get('.search-keyword').type('ca')4 cy.wait(2000)5 cy.get('.products').as('productLocator')6 cy.get('@productLocator').find('.product').should('have.length', 5)7 cy.get(':nth-child(3) > .product-action > button').click()8 cy.get('@productLocator').find('.product').should('have.length', 4)9 cy.get(':nth-child(2) > .product-action > button').click()10 cy.get('@productLocator').find('.product').should('have.length', 3)11 cy.get('.brand').should('have.text', 'GREENKART')12 cy.get('.brand').then(function(logoelement) {13 cy.log(logoelement.text())14 })15 cy.get('.products').find('.product').each(($el, index, $list) => {16 const textVeg = $el.find('h4.product-name').text()17 if(textVeg.includes('Cashews')){18 $el.find('button').click()19 }20 })21 cy.get('.brand').should('have.text', 'GREENKART')22 cy.get('.brand').then(function(logoelement) {23 cy.log(logoelement.text())24 })25 cy.get('.products').find('.product').each(($el, index, $list) => {26 const textVeg = $el.find('h4.product-name').text()27 cy.log(textVeg)28 })29 cy.get('.brand').should('have.text', 'GREENKART')30 cy.get('.brand').then(function(logoelement) {
Using AI Code Generation
1describe('My First Test', function() {2 it('Does not do much!', function() {3 cy.contains('type').click()4 cy.url().should('include', '/commands/actions')5 cy.get('.action-email')6 .type('
Using AI Code Generation
1describe('My First Test', function() {2 it('Does not do much!', function() {3 cy.contains('type').click()4 cy.url().should('include', '/commands/actions')5 cy.get('.action-email')6 .type('
Cypress is a renowned Javascript-based open-source, easy-to-use end-to-end testing framework primarily used for testing web applications. Cypress is a relatively new player in the automation testing space and has been gaining much traction lately, as evidenced by the number of Forks (2.7K) and Stars (42.1K) for the project. LambdaTest’s Cypress Tutorial covers step-by-step guides that will help you learn from the basics till you run automation tests on LambdaTest.
You can elevate your expertise with end-to-end testing using the Cypress automation framework and stay one step ahead in your career by earning a Cypress certification. Check out our Cypress 101 Certification.
Watch this 3 hours of complete tutorial to learn the basics of Cypress and various Cypress commands with the Cypress testing at LambdaTest.
Get 100 minutes of automation test minutes FREE!!