diff --git a/client-ts/Microsoft.AspNetCore.SignalR.Client.TS/Base64EncodedHubProtocol.ts b/client-ts/Microsoft.AspNetCore.SignalR.Client.TS/Base64EncodedHubProtocol.ts index 09e8e9d4e5..acdb6cf194 100644 --- a/client-ts/Microsoft.AspNetCore.SignalR.Client.TS/Base64EncodedHubProtocol.ts +++ b/client-ts/Microsoft.AspNetCore.SignalR.Client.TS/Base64EncodedHubProtocol.ts @@ -15,7 +15,7 @@ export class Base64EncodedHubProtocol implements IHubProtocol { parseMessages(input: any): HubMessage[] { // The format of the message is `size:message;` let pos = input.indexOf(":"); - if (pos == -1 || !input.endsWith(";")) { + if (pos == -1 || input[input.length - 1] != ';') { throw new Error("Invalid payload."); } diff --git a/client-ts/Microsoft.AspNetCore.SignalR.Client.TS/Formatters.ts b/client-ts/Microsoft.AspNetCore.SignalR.Client.TS/Formatters.ts index c2adfbb49f..9f2de9fa0a 100644 --- a/client-ts/Microsoft.AspNetCore.SignalR.Client.TS/Formatters.ts +++ b/client-ts/Microsoft.AspNetCore.SignalR.Client.TS/Formatters.ts @@ -8,7 +8,7 @@ export namespace TextMessageFormat { } export function parse(input: string): string[] { - if (!input.endsWith(RecordSeparator)) { + if (input[input.length - 1] != RecordSeparator) { throw new Error("Message is incomplete."); } @@ -57,7 +57,10 @@ export namespace BinaryMessageFormat { } if (uint8Array.byteLength >= (offset + 8 + size)) { - result.push(uint8Array.slice(offset + 8, offset + 8 + size)) + // IE does not support .slice() so use subarray + result.push(uint8Array.slice + ? uint8Array.slice(offset + 8, offset + 8 + size) + : uint8Array.subarray(offset + 8, offset + 8 + size)); } else { throw new Error("Incomplete message"); diff --git a/client-ts/Microsoft.AspNetCore.SignalR.Client.TS/HubConnection.ts b/client-ts/Microsoft.AspNetCore.SignalR.Client.TS/HubConnection.ts index e8a5ae87e8..87cfb0fae2 100644 --- a/client-ts/Microsoft.AspNetCore.SignalR.Client.TS/HubConnection.ts +++ b/client-ts/Microsoft.AspNetCore.SignalR.Client.TS/HubConnection.ts @@ -55,11 +55,10 @@ export class HubConnection { case MessageType.Completion: let callback = this.callbacks.get(message.invocationId); if (callback != null) { - callback(message); - if (message.type == MessageType.Completion) { this.callbacks.delete(message.invocationId); } + callback(message); } break; default: diff --git a/client-ts/Microsoft.AspNetCore.SignalR.Client.TS/Transports.ts b/client-ts/Microsoft.AspNetCore.SignalR.Client.TS/Transports.ts index 477d080252..3830c24339 100644 --- a/client-ts/Microsoft.AspNetCore.SignalR.Client.TS/Transports.ts +++ b/client-ts/Microsoft.AspNetCore.SignalR.Client.TS/Transports.ts @@ -195,9 +195,6 @@ export class LongPollingTransport implements ITransport { } let pollXhr = new XMLHttpRequest(); - if (transferMode === TransferMode.Binary) { - pollXhr.responseType = "arraybuffer"; - } pollXhr.onload = () => { if (pollXhr.status == 200) { @@ -248,6 +245,11 @@ export class LongPollingTransport implements ITransport { this.pollXhr = pollXhr; this.pollXhr.open("GET", url, true); + if (transferMode === TransferMode.Binary) { + this.pollXhr.responseType = "arraybuffer"; + } + // IE caches xhr requests + this.pollXhr.setRequestHeader("Cache-Control", "no-cache"); // TODO: consider making timeout configurable this.pollXhr.timeout = 120000; this.pollXhr.send(); diff --git a/client-ts/Microsoft.AspNetCore.SignalR.Test.Server/wwwroot/connectionTests.html b/client-ts/Microsoft.AspNetCore.SignalR.Test.Server/wwwroot/connectionTests.html index 83913d4369..f3a938a1eb 100644 --- a/client-ts/Microsoft.AspNetCore.SignalR.Test.Server/wwwroot/connectionTests.html +++ b/client-ts/Microsoft.AspNetCore.SignalR.Test.Server/wwwroot/connectionTests.html @@ -8,8 +8,8 @@ - - + + diff --git a/client-ts/Microsoft.AspNetCore.SignalR.Test.Server/wwwroot/js/common.js b/client-ts/Microsoft.AspNetCore.SignalR.Test.Server/wwwroot/js/common.js index 0572c3ae1d..3be66a15da 100644 --- a/client-ts/Microsoft.AspNetCore.SignalR.Test.Server/wwwroot/js/common.js +++ b/client-ts/Microsoft.AspNetCore.SignalR.Test.Server/wwwroot/js/common.js @@ -1,8 +1,10 @@ -const ECHOENDPOINT_URL = `http://${document.location.host}/echo`; +"use strict"; + +var ECHOENDPOINT_URL = "http://" + document.location.host + "/echo"; function getTransportTypes() { - let transportTypes = [ signalR.TransportType.WebSockets ]; - if (typeof (EventSource) !== "undefined") { + var transportTypes = [signalR.TransportType.WebSockets]; + if (typeof EventSource !== "undefined") { transportTypes.push(signalR.TransportType.ServerSentEvents); } transportTypes.push(signalR.TransportType.LongPolling); @@ -11,14 +13,16 @@ function getTransportTypes() { } function eachTransport(action) { - getTransportTypes().forEach(t => action(t)); + getTransportTypes().forEach(function (t) { + return action(t); + }); } function eachTransportAndProtocol(action) { - let protocols = [ - new signalR.JsonHubProtocol(), - new signalRMsgPack.MessagePackHubProtocol() - ]; - getTransportTypes().forEach(t => - protocols.forEach(p => action(t, p))); -} \ No newline at end of file + var protocols = [new signalR.JsonHubProtocol(), new signalRMsgPack.MessagePackHubProtocol()]; + getTransportTypes().forEach(function (t) { + return protocols.forEach(function (p) { + return action(t, p); + }); + }); +} diff --git a/client-ts/Microsoft.AspNetCore.SignalR.Test.Server/wwwroot/js/connectionTests.js b/client-ts/Microsoft.AspNetCore.SignalR.Test.Server/wwwroot/js/connectionTests.js index b9f782ad66..c7102d3670 100644 --- a/client-ts/Microsoft.AspNetCore.SignalR.Test.Server/wwwroot/js/connectionTests.js +++ b/client-ts/Microsoft.AspNetCore.SignalR.Test.Server/wwwroot/js/connectionTests.js @@ -1,61 +1,58 @@ -describe('connection', () => { - it(`can connect to the server without specifying transport explicitly`, done => { - const message = "Hello World!"; - let connection = new signalR.HttpConnection(ECHOENDPOINT_URL); +"use strict"; - let received = ""; - connection.onDataReceived = data => { +describe('connection', function () { + it("can connect to the server without specifying transport explicitly", function (done) { + var message = "Hello World!"; + var connection = new signalR.HttpConnection(ECHOENDPOINT_URL); + + var received = ""; + connection.onDataReceived = function (data) { received += data; if (data == message) { connection.stop(); } - } + }; - connection.onClosed = error => { + connection.onClosed = function (error) { expect(error).toBeUndefined(); done(); - } + }; - connection.start() - .then(() => { - connection.send(message); - }) - .catch(e => { - fail(); - done(); - }); + connection.start().then(function () { + connection.send(message); + }).catch(function (e) { + fail(); + done(); + }); }); - eachTransport(transportType => { - it(`over ${signalR.TransportType[transportType]} can send and receive messages`, done => { - const message = "Hello World!"; - let connection = new signalR.HttpConnection(ECHOENDPOINT_URL, - { - transport: transportType, - logger: new signalR.ConsoleLogger(signalR.LogLevel.Information) - }); - - let received = ""; - connection.onDataReceived = data => { + eachTransport(function (transportType) { + it("over " + signalR.TransportType[transportType] + " can send and receive messages", function (done) { + var message = "Hello World!"; + var connection = new signalR.HttpConnection(ECHOENDPOINT_URL, { + transport: transportType, + logger: new signalR.ConsoleLogger(signalR.LogLevel.Information) + }); + + var received = ""; + connection.onDataReceived = function (data) { received += data; if (data == message) { connection.stop(); } - } + }; - connection.onClosed = error => { + connection.onClosed = function (error) { expect(error).toBeUndefined(); done(); - } + }; - connection.start() - .then(() => { - connection.send(message); - }) - .catch(e => { - fail(); - done(); - }); + connection.start().then(function () { + connection.send(message); + }).catch(function (e) { + fail(); + done(); + }); }); }); -}); \ No newline at end of file +}); diff --git a/client-ts/Microsoft.AspNetCore.SignalR.Test.Server/wwwroot/js/hubConnectionTests.js b/client-ts/Microsoft.AspNetCore.SignalR.Test.Server/wwwroot/js/hubConnectionTests.js index d501b910c7..75ccc3795b 100644 --- a/client-ts/Microsoft.AspNetCore.SignalR.Test.Server/wwwroot/js/hubConnectionTests.js +++ b/client-ts/Microsoft.AspNetCore.SignalR.Test.Server/wwwroot/js/hubConnectionTests.js @@ -1,194 +1,149 @@ -const TESTHUBENDPOINT_URL = `http://${document.location.host}/testhub`; - -describe('hubConnection', () => { - eachTransportAndProtocol((transportType, protocol) => { - describe(`${protocol.name} over ${signalR.TransportType[transportType]} transport`, () => { - it(`can invoke server method and receive result`, done => { - const message = "你好,世界!"; - let logger = new signalR.ConsoleLogger(signalR.LogLevel.Information); - let hubConnection = new signalR.HubConnection(new signalR.HttpConnection( - TESTHUBENDPOINT_URL, - { transport: transportType, logger: logger }), - logger, - protocol); - hubConnection.onClosed = error => { +'use strict'; + +var TESTHUBENDPOINT_URL = 'http://' + document.location.host + '/testhub'; + +describe('hubConnection', function () { + eachTransportAndProtocol(function (transportType, protocol) { + describe(protocol.name + ' over ' + signalR.TransportType[transportType] + ' transport', function () { + + it('can invoke server method and receive result', function (done) { + var message = "你好,世界!"; + var logger = new signalR.ConsoleLogger(signalR.LogLevel.Information); + var hubConnection = new signalR.HubConnection(new signalR.HttpConnection(TESTHUBENDPOINT_URL, { transport: transportType, logger: logger }), logger, protocol); + hubConnection.onClosed = function (error) { expect(error).toBe(undefined); done(); - } - - hubConnection.start() - .then(() => { - hubConnection.invoke('Echo', message) - .then(result => { - expect(result).toBe(message); - }) - .catch(e => { - fail(e); - }) - .then(() => { - hubConnection.stop(); - }) - }) - .catch(e => { + }; + + hubConnection.start().then(function () { + hubConnection.invoke('Echo', message).then(function (result) { + expect(result).toBe(message); + }).catch(function (e) { fail(e); - done(); + }).then(function () { + hubConnection.stop(); }); + }).catch(function (e) { + fail(e); + done(); + }); }); - it(`can stream server method and receive result`, done => { - let logger = new signalR.ConsoleLogger(signalR.LogLevel.Information); - let hubConnection = new signalR.HubConnection(new signalR.HttpConnection( - TESTHUBENDPOINT_URL, - { transport: transportType, logger: logger }), - logger, - protocol); + it('can stream server method and receive result', function (done) { + var logger = new signalR.ConsoleLogger(signalR.LogLevel.Information); + var hubConnection = new signalR.HubConnection(new signalR.HttpConnection(TESTHUBENDPOINT_URL, { transport: transportType, logger: logger }), logger, protocol); - hubConnection.onClosed = error => { + hubConnection.onClosed = function (error) { expect(error).toBe(undefined); done(); - } - - let received = []; - hubConnection.start() - .then(() => { - hubConnection.stream('Stream') - .subscribe({ - next: (item) => { - received.push(item); - }, - error: (err) => { - fail(err); - hubConnection.stop(); - }, - complete: () => { - expect(received).toEqual(["a", "b", "c"]); - hubConnection.stop(); - } - }); - }) - .catch(e => { - fail(e); - done(); + }; + + var received = []; + hubConnection.start().then(function () { + hubConnection.stream('Stream').subscribe({ + next: function next(item) { + received.push(item); + }, + error: function error(err) { + fail(err); + hubConnection.stop(); + }, + complete: function complete() { + expect(received).toEqual(["a", "b", "c"]); + hubConnection.stop(); + } }); + }).catch(function (e) { + fail(e); + done(); + }); }); - it(`rethrows an exception from the server when invoking`, done => { - const errorMessage = "An error occurred."; - - let logger = new signalR.ConsoleLogger(signalR.LogLevel.Information); - let hubConnection = new signalR.HubConnection(new signalR.HttpConnection( - TESTHUBENDPOINT_URL, - { transport: transportType, logger: logger }), - logger, - protocol); - - hubConnection.start() - .then(() => { - hubConnection.invoke('ThrowException', errorMessage) - .then(() => { - // exception expected but none thrown - fail(); - }) - .catch(e => { - expect(e.message).toBe(errorMessage); - }) - .then(() => { - return hubConnection.stop(); - }) - .then(() => { - done(); - }); - }) - .catch(e => { - fail(e); + it('rethrows an exception from the server when invoking', function (done) { + var errorMessage = "An error occurred."; + + var logger = new signalR.ConsoleLogger(signalR.LogLevel.Information); + var hubConnection = new signalR.HubConnection(new signalR.HttpConnection(TESTHUBENDPOINT_URL, { transport: transportType, logger: logger }), logger, protocol); + + hubConnection.start().then(function () { + hubConnection.invoke('ThrowException', errorMessage).then(function () { + // exception expected but none thrown + fail(); + }).catch(function (e) { + expect(e.message).toBe(errorMessage); + }).then(function () { + return hubConnection.stop(); + }).then(function () { done(); }); + }).catch(function (e) { + fail(e); + done(); + }); }); - it(`rethrows an exception from the server when streaming`, done => { - const errorMessage = "An error occurred."; - - let logger = new signalR.ConsoleLogger(signalR.LogLevel.Information); - let hubConnection = new signalR.HubConnection(new signalR.HttpConnection( - TESTHUBENDPOINT_URL, - { transport: transportType, logger: logger }), - logger, - protocol); - - hubConnection.start() - .then(() => { - hubConnection.stream('ThrowException', errorMessage) - .subscribe({ - next: (item) => { - fail(); - }, - error: (err) => { - expect(err.message).toEqual("An error occurred."); - done(); - }, - complete: () => { - fail(); - } - }); - - }) - .catch(e => { - fail(e); - done(); + it('rethrows an exception from the server when streaming', function (done) { + var errorMessage = "An error occurred."; + + var logger = new signalR.ConsoleLogger(signalR.LogLevel.Information); + var hubConnection = new signalR.HubConnection(new signalR.HttpConnection(TESTHUBENDPOINT_URL, { transport: transportType, logger: logger }), logger, protocol); + + hubConnection.start().then(function () { + hubConnection.stream('ThrowException', errorMessage).subscribe({ + next: function next(item) { + fail(); + }, + error: function error(err) { + expect(err.message).toEqual("An error occurred."); + done(); + }, + complete: function complete() { + fail(); + } }); + }).catch(function (e) { + fail(e); + done(); + }); }); - it(`can receive server calls`, done => { - let logger = new signalR.ConsoleLogger(signalR.LogLevel.Information); - let hubConnection = new signalR.HubConnection(new signalR.HttpConnection( - TESTHUBENDPOINT_URL, - { transport: transportType, logger: logger }), - logger, - protocol); + it('can receive server calls', function (done) { + var logger = new signalR.ConsoleLogger(signalR.LogLevel.Information); + var hubConnection = new signalR.HubConnection(new signalR.HttpConnection(TESTHUBENDPOINT_URL, { transport: transportType, logger: logger }), logger, protocol); - const message = "你好 SignalR!"; + var message = "你好 SignalR!"; - let callbackPromise = new Promise((resolve, reject) => { - hubConnection.on("Message", msg => { - expect(msg).toBe(message); - resolve(); - }); + hubConnection.on("Message", function (msg) { + expect(msg).toBe(message); + done(); }); - hubConnection.start() - .then(() => { - return Promise.all([hubConnection.invoke('InvokeWithString', message), callbackPromise]); - }) - .then(() => { - return stop(); - }) - .then(() => { - done(); - }) - .catch(e => { - fail(e); - done(); - }); + hubConnection.start().then(function () { + return hubConnection.invoke('InvokeWithString', message); + }) + .then(function() { + return hubConnection.stop(); + }) + .catch(function (e) { + fail(e); + done(); + }); }); - it(`closed with error if hub cannot be created`, done => { - let errorRegex = { - WebSockets: "1011", // Message is browser specific (e.g. 'Websocket closed with status code: 1011') + it('closed with error if hub cannot be created', function (done) { + var errorRegex = { + WebSockets: "1011|1005", // Message is browser specific (e.g. 'Websocket closed with status code: 1011'), Edge and IE report 1005 even though the server sent 1011 LongPolling: "Internal Server Error", ServerSentEvents: "Error occurred" }; - let logger = new signalR.ConsoleLogger(signalR.LogLevel.Information); - let hubConnection = new signalR.HubConnection(new signalR.HttpConnection( - `http://${document.location.host}/uncreatable`, - { transport: transportType, logger: logger }), - logger, - protocol); + var logger = new signalR.ConsoleLogger(signalR.LogLevel.Information); + var hubConnection = new signalR.HubConnection(new signalR.HttpConnection('http://' + document.location.host + '/uncreatable', { transport: transportType, logger: logger }), logger, protocol); - hubConnection.onClosed = error => { + hubConnection.onClosed = function (error) { expect(error.message).toMatch(errorRegex[signalR.TransportType[transportType]]); done(); - } + }; hubConnection.start(); }); }); diff --git a/client-ts/Microsoft.AspNetCore.SignalR.Test.Server/wwwroot/js/webSocketTests.js b/client-ts/Microsoft.AspNetCore.SignalR.Test.Server/wwwroot/js/webSocketTests.js index 6c437ae49f..42ead2c96b 100644 --- a/client-ts/Microsoft.AspNetCore.SignalR.Test.Server/wwwroot/js/webSocketTests.js +++ b/client-ts/Microsoft.AspNetCore.SignalR.Test.Server/wwwroot/js/webSocketTests.js @@ -1,22 +1,24 @@ +'use strict'; + describe('WebSockets', function () { - it('can be used to connect to SignalR', done => { - const message = "message"; + it('can be used to connect to SignalR', function (done) { + var message = "message"; - let webSocket = new WebSocket(ECHOENDPOINT_URL.replace(/^http/, "ws")); + var webSocket = new WebSocket(ECHOENDPOINT_URL.replace(/^http/, "ws")); - webSocket.onopen = () => { + webSocket.onopen = function () { webSocket.send(message); }; var received = ""; - webSocket.onmessage = event => { + webSocket.onmessage = function (event) { received += event.data; if (received === message) { webSocket.close(); } }; - webSocket.onclose = event => { + webSocket.onclose = function (event) { if (!event.wasClean) { fail("connection closed with unexpected status code: " + event.code + " " + event.reason); }