Compare commits

...

4 Commits

Author SHA1 Message Date
8344624e6b Added license 2021-08-26 21:56:23 +02:00
9cbd655a4a Added npm install to launch script 2021-08-26 21:38:09 +02:00
34050291a8 Increased canvas size 2021-08-26 21:30:39 +02:00
78877f1211 Consolidated the server into the project
Added npm scripts to build and launch the whole project
2021-08-26 21:28:10 +02:00
14 changed files with 286 additions and 9 deletions

9
LICENSE Normal file
View File

@@ -0,0 +1,9 @@
Copyright (c) 2021 Robin Steinberg, All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

16
README.md Normal file
View File

@@ -0,0 +1,16 @@
# HTML Canvas with WebSocket
## About
This is a demo app that allows you to draw on an HTML canvas. Everythng that gets drawn will be
transmitted to a server using websocket and displayed by a receiver app.
## Dependencies
This app needs Node.js and npm to build and run.
## Running the app
Open the command line in the project directory and run ```npm run launch```
Then open your browser and navigate to http://localhost:8080.

View File

@@ -10,8 +10,8 @@
<style>
#canvas {
width: 500px;
height: 500px;
width: 100%;
height: 800px;
border: 1px solid black;
}
</style>

View File

@@ -8,7 +8,9 @@
"watch": "tsc -watch -p ./",
"serve": "serve -l 8080 .",
"debug": "npm-run-all --parallel watch serve",
"test": "echo \"Error: no test specified\" && exit 1"
"test": "echo \"Error: no test specified\" && exit 1",
"run-server": "cd server && npm run launch",
"launch": "npm install && npm-run-all --parallel run-server build serve"
},
"author": "",
"license": "ISC",

View File

@@ -10,8 +10,8 @@
<style>
#canvas {
width: 500px;
height: 500px;
width: 100%;
height: 800px;
border: 1px solid black;
}
</style>

102
server/.gitignore vendored Normal file
View File

@@ -0,0 +1,102 @@
dist/
node_modules/
.node_modules/
built/*
tests/cases/rwc/*
tests/cases/test262/*
tests/cases/perf/*
!tests/cases/webharness/compilerToString.js
test-args.txt
~*.docx
\#*\#
.\#*
tests/baselines/local/*
tests/baselines/local.old/*
tests/services/baselines/local/*
tests/baselines/prototyping/local/*
tests/baselines/rwc/*
tests/baselines/test262/*
tests/baselines/reference/projectOutput/*
tests/baselines/local/projectOutput/*
tests/baselines/reference/testresults.tap
tests/services/baselines/prototyping/local/*
tests/services/browser/typescriptServices.js
src/harness/*.js
src/compiler/diagnosticInformationMap.generated.ts
src/compiler/diagnosticMessages.generated.json
src/parser/diagnosticInformationMap.generated.ts
src/parser/diagnosticMessages.generated.json
rwc-report.html
*.swp
build.json
*.actual
tests/webTestServer.js
tests/webTestServer.js.map
tests/webhost/*.d.ts
tests/webhost/webtsc.js
tests/cases/**/*.js
!tests/cases/docker/*.js/
tests/cases/**/*.js.map
*.config
scripts/eslint/built/
scripts/debug.bat
scripts/run.bat
scripts/word2md.js
scripts/buildProtocol.js
scripts/ior.js
scripts/authors.js
scripts/configurePrerelease.js
scripts/configureLanguageServiceBuild.js
scripts/open-user-pr.js
scripts/open-cherry-pick-pr.js
scripts/processDiagnosticMessages.d.ts
scripts/processDiagnosticMessages.js
scripts/produceLKG.js
scripts/importDefinitelyTypedTests/importDefinitelyTypedTests.js
scripts/generateLocalizedDiagnosticMessages.js
scripts/request-pr-review.js
scripts/*.js.map
scripts/typings/
coverage/
internal/
**/.DS_Store
.settings
**/.vs
**/.vscode/*
!**/.vscode/tasks.json
!**/.vscode/settings.template.json
!**/.vscode/launch.template.json
!**/.vscode/extensions.json
!tests/cases/projects/projectOption/**/node_modules
!tests/cases/projects/NodeModulesSearch/**/*
!tests/baselines/reference/project/nodeModules*/**/*
.idea
yarn.lock
yarn-error.log
.parallelperf.*
tests/cases/user/*/package-lock.json
tests/cases/user/*/node_modules/
tests/cases/user/*/**/*.js
tests/cases/user/*/**/*.js.map
tests/cases/user/*/**/*.d.ts
!tests/cases/user/zone.js/
!tests/cases/user/bignumber.js/
!tests/cases/user/discord.js/
tests/baselines/reference/dt
.failed-tests
TEST-results.xml
package-lock.json
tests/cases/user/npm/npm
tests/cases/user/TypeScript-React-Starter/TypeScript-React-Starter
tests/cases/user/TypeScript-Node-Starter/TypeScript-Node-Starter
tests/cases/user/TypeScript-React-Native-Starter/TypeScript-React-Native-Starter
tests/cases/user/TypeScript-Vue-Starter/TypeScript-Vue-Starter
tests/cases/user/TypeScript-WeChat-Starter/TypeScript-WeChat-Starter
tests/cases/user/create-react-app/create-react-app
tests/cases/user/fp-ts/fp-ts
tests/cases/user/webpack/webpack
tests/cases/user/puppeteer/puppeteer
tests/cases/user/axios-src/axios-src
tests/cases/user/prettier/prettier
.eslintcache

17
server/package.json Normal file
View File

@@ -0,0 +1,17 @@
{
"scripts": {
"build": "npm install && tsc -p ./",
"start": "node dist/app.js",
"launch": "npm-run-all build start"
},
"devDependencies": {
"@tsconfig/node16": "^1.0.2",
"@types/node": "^16.7.1",
"@types/ws": "^7.4.7",
"npm-run-all": "^4.1.5",
"typescript": "^4.3.5"
},
"dependencies": {
"ws": "^8.2.0"
}
}

102
server/ts/app.ts Normal file
View File

@@ -0,0 +1,102 @@
import WebSocket from 'ws';
import Coordinates from './coordinates';
const wss = new WebSocket.Server({ port: 8081 });
const receivers: WebSocket[] = [];
let sender: WebSocket | null = null;
const paths = [] as Coordinates[][];
let currentPath = [] as Coordinates[];
wss.on('connection', ws => {
console.log('CONNECTION incoming');
ws.once('message', message => {
const str = message.toString();
switch (str) {
case 'SENDER':
setSender(ws);
break;
case 'RECEIVER':
addReceiver(ws)
break;
default:
console.log('Unknown register code: ' + str);
break;
}
});
});
console.log('READY');
function addReceiver(ws: WebSocket) {
console.log('RECEIVER registered');
for (const path of paths) {
ws.send('START');
path.forEach(c => ws.send(JSON.stringify(c)));
ws.send('STOP');
}
receivers.push(ws);
ws.onclose = () => {
// Remove receiver when connection closes
for (const [i, recv] of receivers.entries()) {
if (ws === recv) {
receivers.splice(i, 1);
}
}
};
}
function setSender(ws: WebSocket) {
console.log('SENDER is being registered')
if (sender) {
console.log('Removing current sender...')
sender.close();
clearPaths();
}
sender = ws;
ws.on('message', msg => processMessage(msg));
}
function processMessage(message: WebSocket.Data) {
const text = message.toString();
switch (text) {
case 'START':
startPath();
break;
case 'STOP':
finishPath();
break;
default:
processCoordinates(text);
break;
}
}
function processCoordinates(text: string) {
console.log('COORDINATES received: ' + text);
console.log('SENDING to ' + receivers.length, 'clients');
receivers.forEach(r => r.send(text));
currentPath.push(JSON.parse(text));
}
function startPath() {
currentPath = [];
receivers.forEach(r => r.send('START'));
}
function finishPath() {
paths.push(currentPath);
receivers.forEach(r => r.send("STOP"));
}
function clearPaths() {
paths.splice(0, paths.length);
receivers.forEach(r => r.send('CLEAR'));
console.log('Paths have been cleared');
}

9
server/ts/coordinates.ts Normal file
View File

@@ -0,0 +1,9 @@
export default class Coordinates {
public x: number;
public y: number;
constructor(x: number, y: number) {
this.x = x;
this.y = y;
}
}

10
server/tsconfig.json Normal file
View File

@@ -0,0 +1,10 @@
{
"extends": "@tsconfig/node16/tsconfig.json",
"compilerOptions": {
"sourceMap": true,
"outDir": "dist",
"moduleResolution": "node"
},
"include": ["ts/**/*"],
"exclude": ["node_modules", "**/*.spec.ts"]
}

View File

@@ -1,8 +1,8 @@
import CanvasUtil from './canvas-util/canvasUtil.js';
import Coordinates from './canvas-util/coordinates.js';
import { getWebsocketUrl } from "./websocket/websocket.js";
class CanvasReceiverController {
private canvas!: HTMLCanvasElement;
private canvasDiv: HTMLDivElement;
private canvasUtil: CanvasUtil;
private ws: WebSocket;
@@ -23,7 +23,7 @@ class CanvasReceiverController {
alert('Canvas API unavailable, drawing will not work!');
}
this.ws = new WebSocket('ws://localhost:8081', 'json');
this.ws = new WebSocket(getWebsocketUrl(), 'json');
this.ws.onmessage = message => this.processMessage(message);
this.ws.onopen = () => this.ws.send('RECEIVER');

View File

@@ -1,5 +1,6 @@
import CanvasUtil from "./canvas-util/canvasUtil.js";
import Coordinates from "./canvas-util/coordinates.js";
import { getWebsocketUrl } from "./websocket/websocket.js";
class CanvasSenderController {
private canvasUtil: CanvasUtil;
@@ -28,7 +29,7 @@ class CanvasSenderController {
canvas.addEventListener('touchmove', e => this.onMouseMove(e.touches[0]));
}
this.ws = new WebSocket('ws://localhost:8081', 'json');
this.ws = new WebSocket(getWebsocketUrl(), 'json');
this.ws.onopen = () => this.ws.send('SENDER');
}

View File

@@ -0,0 +1,9 @@
export function getWebsocketUrl(): string {
let scheme = 'ws';
if (document.location.protocol === 'https:') {
scheme += 's';
}
return scheme + '://' + document.location.hostname + ':8081';
}

View File

@@ -8,4 +8,4 @@
"extends": "@tsconfig/recommended/tsconfig.json",
"include": ["ts/**/*"],
"exclude": ["node_modules", "**/*.spec.ts"]
}
}