From 8ae4c4dbd6773fb654041a61e75114258e5029bf Mon Sep 17 00:00:00 2001 From: Stephen Halter Date: Sun, 17 Feb 2019 07:52:18 -0800 Subject: [PATCH] Add SignalR web worker sample and test (#7378) --- .../ts/FunctionalTests/FunctionalTests.csproj | 13 ++-- .../scripts/karma.local.conf.js | 7 +- .../ts/FunctionalTests/ts/WebWorkerTests.ts | 70 +++++++++++++++++++ .../clients/ts/FunctionalTests/ts/index.ts | 1 + .../SignalRSamples/SignalRSamples.csproj | 8 ++- .../SignalRSamples/wwwroot/worker.html | 54 ++++++++++++++ .../samples/SignalRSamples/wwwroot/worker.js | 23 ++++++ 7 files changed, 167 insertions(+), 9 deletions(-) create mode 100644 src/SignalR/clients/ts/FunctionalTests/ts/WebWorkerTests.ts create mode 100644 src/SignalR/samples/SignalRSamples/wwwroot/worker.html create mode 100644 src/SignalR/samples/SignalRSamples/wwwroot/worker.js diff --git a/src/SignalR/clients/ts/FunctionalTests/FunctionalTests.csproj b/src/SignalR/clients/ts/FunctionalTests/FunctionalTests.csproj index e402086f43..6819bd1c36 100644 --- a/src/SignalR/clients/ts/FunctionalTests/FunctionalTests.csproj +++ b/src/SignalR/clients/ts/FunctionalTests/FunctionalTests.csproj @@ -1,4 +1,4 @@ - + netcoreapp3.0 @@ -21,6 +21,7 @@ + @@ -49,8 +50,8 @@ - + @@ -65,10 +66,12 @@ - - + + + - + + diff --git a/src/SignalR/clients/ts/FunctionalTests/scripts/karma.local.conf.js b/src/SignalR/clients/ts/FunctionalTests/scripts/karma.local.conf.js index 4487671000..8837d36e88 100644 --- a/src/SignalR/clients/ts/FunctionalTests/scripts/karma.local.conf.js +++ b/src/SignalR/clients/ts/FunctionalTests/scripts/karma.local.conf.js @@ -8,6 +8,7 @@ try { const ChromeHeadlessBrowser = require("karma-chrome-launcher")["launcher:ChromeHeadless"][1]; const ChromiumHeadlessBrowser = require("karma-chrome-launcher")["launcher:ChromiumHeadless"][1]; const FirefoxHeadlessBrowser = require("karma-firefox-launcher")["launcher:FirefoxHeadless"][1]; + const FirefoxDeveloperHeadlessBrowser = require("karma-firefox-launcher")["launcher:FirefoxDeveloperHeadless"][1]; const EdgeBrowser = require("karma-edge-launcher")["launcher:Edge"][1]; const SafariBrowser = require("karma-safari-launcher")["launcher:Safari"][1]; const IEBrowser = require("karma-ie-launcher")["launcher:IE"][1]; @@ -33,16 +34,20 @@ try { if (path && browserExists(path)) { console.log(`Located ${name} at ${path}.`); browsers.push(name); + return true; } else { console.log(`Unable to locate ${name}. Skipping.`); + return false; } } // We use the launchers themselves to figure out if the browser exists. It's a bit sneaky, but it works. tryAddBrowser("ChromeHeadlessNoSandbox", new ChromeHeadlessBrowser(() => { }, {})); tryAddBrowser("ChromiumHeadlessIgnoreCert", new ChromiumHeadlessBrowser(() => { }, {})); - tryAddBrowser("FirefoxHeadless", new FirefoxHeadlessBrowser(0, () => { }, {})); + if (!tryAddBrowser("FirefoxHeadless", new FirefoxHeadlessBrowser(0, () => { }, {}))) { + tryAddBrowser("FirefoxDeveloperHeadless", new FirefoxDeveloperHeadlessBrowser(0, () => { }, {})); + } // We need to receive an argument from the caller, but globals don't seem to work, so we use an environment variable. if (process.env.ASPNETCORE_SIGNALR_TEST_ALL_BROWSERS === "true") { diff --git a/src/SignalR/clients/ts/FunctionalTests/ts/WebWorkerTests.ts b/src/SignalR/clients/ts/FunctionalTests/ts/WebWorkerTests.ts new file mode 100644 index 0000000000..6cd51ae722 --- /dev/null +++ b/src/SignalR/clients/ts/FunctionalTests/ts/WebWorkerTests.ts @@ -0,0 +1,70 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +import { ENDPOINT_BASE_URL } from "./Common"; + +// On slower CI machines, these tests sometimes take longer than 5s +jasmine.DEFAULT_TIMEOUT_INTERVAL = 10 * 1000; + +describe("WebWorkers", () => { + it("can use SignalR client", (done) => { + if (typeof window !== "undefined" && (window as any).Worker) { + const workerSrc = ` + var connection = null; + + onmessage = function (e) { + if (connection === null) { + postMessage('initialized'); + + importScripts(e.data + '/lib/signalr-webworker/signalr.js'); + + connection = new signalR.HubConnectionBuilder() + .withUrl(e.data + '/testhub') + .build(); + + connection.on('message', function (message) { + postMessage('Received message: ' + message); + }); + + connection.start().then(function () { + postMessage('connected'); + }); + } else if (connection.state == signalR.HubConnectionState.Connected) { + connection.invoke('invokeWithString', e.data); + } else { + postMessage('Attempted to send message while disconnected.') + } + }`; + + // Load worker from a blob since workers MUST come from the same origin despite CORS configuration. + // https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers#Spawning_subworkers + const blob = new Blob([workerSrc], { type: "application/javascript" }); + const worker = new Worker(URL.createObjectURL(blob)); + + const testMessage = "Hello World!"; + + const initWorkerTimeout = setTimeout(() => { + console.log("Web workers are supported by this browser, but don't work!?"); + worker.terminate(); + done(); + }, jasmine.DEFAULT_TIMEOUT_INTERVAL / 2); + + worker.postMessage(ENDPOINT_BASE_URL); + + worker.onmessage = (e) => { + if (e.data === "initialized") { + clearTimeout(initWorkerTimeout); + } else if (e.data === "connected") { + worker.postMessage(testMessage); + } else { + expect(e.data).toBe(`Received message: ${testMessage}`); + worker.terminate(); + done(); + } + }; + } else { + console.log("Web workers are not supported by this browser!"); + done(); + } + }); +}); diff --git a/src/SignalR/clients/ts/FunctionalTests/ts/index.ts b/src/SignalR/clients/ts/FunctionalTests/ts/index.ts index 0a2eca2ed3..06ca448f95 100644 --- a/src/SignalR/clients/ts/FunctionalTests/ts/index.ts +++ b/src/SignalR/clients/ts/FunctionalTests/ts/index.ts @@ -11,3 +11,4 @@ import "./LogBannerReporter"; import "./ConnectionTests"; import "./HubConnectionTests"; import "./WebSocketTests"; +import "./WebWorkerTests"; diff --git a/src/SignalR/samples/SignalRSamples/SignalRSamples.csproj b/src/SignalR/samples/SignalRSamples/SignalRSamples.csproj index bc9634b87f..25201e0f9a 100644 --- a/src/SignalR/samples/SignalRSamples/SignalRSamples.csproj +++ b/src/SignalR/samples/SignalRSamples/SignalRSamples.csproj @@ -24,10 +24,12 @@ - - + + + - + + diff --git a/src/SignalR/samples/SignalRSamples/wwwroot/worker.html b/src/SignalR/samples/SignalRSamples/wwwroot/worker.html new file mode 100644 index 0000000000..afe8b7f748 --- /dev/null +++ b/src/SignalR/samples/SignalRSamples/wwwroot/worker.html @@ -0,0 +1,54 @@ + + + + + + + +

SignalR Web Worker Sample

+ +
+
+ + +
+
+ +
    + + + + diff --git a/src/SignalR/samples/SignalRSamples/wwwroot/worker.js b/src/SignalR/samples/SignalRSamples/wwwroot/worker.js new file mode 100644 index 0000000000..61a9b0ae9f --- /dev/null +++ b/src/SignalR/samples/SignalRSamples/wwwroot/worker.js @@ -0,0 +1,23 @@ +importScripts('lib/signalr-webworker/signalr.js'); + +var connection = null; + +onmessage = function (e) { + if (connection === null) { + connection = new signalR.HubConnectionBuilder() + .withUrl(e.data + '/default') + .build(); + + connection.on('send', function (message) { + postMessage('Received message: ' + message); + }); + + connection.start().then(function () { + postMessage('connected'); + }); + } else if (connection.connectionState == signalR.HubConnectionState.Connected) { + connection.invoke('send', e.data); + } else { + postMessage('Attempted to send message while disconnected.') + } +};