From 52bb816282bb0cbc0122dcfd44bc6278d3b17a03 Mon Sep 17 00:00:00 2001 From: Ivan Li Date: Thu, 4 Aug 2022 09:56:05 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A4=9A=E7=BA=BF=E7=A8=8B=E5=8E=8B?= =?UTF-8?q?=E6=B5=8B=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .editorconfig | 12 ++ .gitignore | 130 ++++++++++++++++++ .npmrc | 1 + client.js | 44 +++++++ index.js | 118 +++++++++++++++++ logger.js | 19 +++ package.json | 22 ++++ pnpm-lock.yaml | 308 +++++++++++++++++++++++++++++++++++++++++++ received-packages.js | 10 ++ test-group.js | 37 ++++++ 10 files changed, 701 insertions(+) create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100644 .npmrc create mode 100644 client.js create mode 100644 index.js create mode 100644 logger.js create mode 100644 package.json create mode 100644 pnpm-lock.yaml create mode 100644 received-packages.js create mode 100644 test-group.js diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..ebe51d3 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,12 @@ +# EditorConfig is awesome: https://EditorConfig.org + +# top-most EditorConfig file +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = false +insert_final_newline = false \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c6bba59 --- /dev/null +++ b/.gitignore @@ -0,0 +1,130 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) +web_modules/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional stylelint cache +.stylelintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) +.cache +.parcel-cache + +# Next.js build output +.next +out + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and not Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# vuepress v2.x temp and cache directory +.temp +.cache + +# Docusaurus cache and generated files +.docusaurus + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# yarn v2 +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..bf2e764 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +shamefully-hoist=true diff --git a/client.js b/client.js new file mode 100644 index 0000000..524dbc0 --- /dev/null +++ b/client.js @@ -0,0 +1,44 @@ +import * as Colyseus from "colyseus.js"; +import { logError, writeLine } from "./logger.js"; +import { markReceive } from "./received-packages.js"; + +export class Client { + client; + room; + index; + packageIndex = 0; + + constructor(index) { + this.index = index; + } + + async joinRoom() { + this.client = new Colyseus.Client('wss://api-meta.sequenxe.com/socket'); + + this.room = await this.client.joinOrCreate("my_room"); + this.room.onStateChange((state) => { + if (this.index !== 0) { + return; + } + markReceive(); + writeLine(state); + }); + this.room.onError((code, message) => { + logError('error:', code, message); + }) + } + + testOnce() { + this.room.send("updatePlayer", { + x: +Math.random().toFixed(1), + y: +Math.random().toFixed(1), + z: +Math.random().toFixed(1), + rotationX: +Math.random().toFixed(1), + rotationY: +Math.random().toFixed(1), + rotationZ: +Math.random().toFixed(1), + animation: Math.random().toFixed(1), + nickname: Math.random().toFixed(1), + characterKey: `${this.index}#${this.packageIndex++}`, + }); + } +} \ No newline at end of file diff --git a/index.js b/index.js new file mode 100644 index 0000000..56dbb30 --- /dev/null +++ b/index.js @@ -0,0 +1,118 @@ +import enquirer from 'enquirer'; +const { NumberPrompt, Select } = enquirer; +import ora from 'ora'; +import { packageCounts, rps } from './received-packages.js'; +import { Worker } from 'worker_threads'; +import { dirname } from 'path'; +import { fileURLToPath } from 'url'; +import { Client } from './client.js'; + +const workerCounts = 4; + +const testGroupWorkers = generateWorkers(); + + + +const {mainClient, numberOfPlayers} = await getConnectedWorkers(); +await test(); + + +function generateWorkers() { + return new Array(workerCounts).fill(undefined).map(() => new Worker( + dirname(fileURLToPath(import.meta.url)) + '/test-group.js', + )); +} + +async function test() { + const frequency = await new Select({ + name: 'frequency', + message: 'frequency', + choices: [ + { name: '10tps', value: 10 }, + { name: '20tps', value: 20 }, + { name: '30tps', value: 30 }, + { name: '60tps', value: 60 }, + ] + }).run(); + + const spinner = ora('Testing...').start(); + + let times = 0; + let softStartup = 1; + setInterval(() => { + testGroupWorkers.forEach(worker => worker.postMessage({ + type: 'testOnce', + limit: softStartup, + })); + mainClient.testOnce(); + spinner.text = `${softStartup} player(s) sent ${++times} times,\trps:\t${rps}, counts: ${packageCounts}`; + }, 1000 / +/\d+/.exec(frequency)[0]); + + const timer = setInterval(() => { + if (++softStartup >= numberOfPlayers) { + clearInterval(timer); + } + }, 100); + +} + +async function getConnectedWorkers() { + const numberOfPlayers = await new NumberPrompt({ + name: 'number', + message: 'number of players', + }).run(); + + if (numberOfPlayers < 1) { + throw new Error('number of players must be greater than 0'); + } + const spinner = ora('Connecting server and join room.').start(); + + + const mainClient = new Client(0); + + let assignedCursor = 1; + const groupSize = Math.ceil((numberOfPlayers - assignedCursor) / workerCounts); + + await Promise.all( + testGroupWorkers.map(worker => new Promise(resolve => { + worker.on('message', message => { + if (message.type === 'workersGenerated') { + resolve(); + } + }); + worker.postMessage({ + type: 'generateWorkers', + start: assignedCursor, + end: Math.min(assignedCursor += groupSize, numberOfPlayers), + }); + })) + ); + + + let connected = 1; + await mainClient.joinRoom(); + spinner.text = `Connected ${connected}/${numberOfPlayers}.`; + + await new Promise(resolve => { + testGroupWorkers.forEach(worker => { + worker.on('message', message => { + if (message.type === 'oneWorkerJoined') { + connected++; + spinner.text = `Connected ${connected}/${numberOfPlayers}.`; + if (connected === numberOfPlayers) { + resolve(); + } + } + }); + worker.on('joinRoomFailed', err => { + throw err; + }) + worker.postMessage({ + type: 'joinRoom', + }); + }); + }) + + spinner.succeed('Connected server and join room.'); + return {mainClient, numberOfPlayers}; +} diff --git a/logger.js b/logger.js new file mode 100644 index 0000000..35a931e --- /dev/null +++ b/logger.js @@ -0,0 +1,19 @@ +import { createWriteStream } from 'fs'; +import { fileURLToPath } from 'url'; +import { dirname } from 'path'; + +const statefileStream = createWriteStream( + `${dirname(fileURLToPath(import.meta.url))}/logs/state.log`, + { flags: 'w' }, + ); +const erroutfileStream = createWriteStream( + `${dirname(fileURLToPath(import.meta.url))}/logs/error.log`, + { flags: 'w' }, + ); + +export const writeLine = (obj) => { + statefileStream.write(JSON.stringify(obj) + '\n'); +} +export const logError = (...args) => { + erroutfileStream.write(JSON.stringify(args) + '\n'); +} \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..c4efb2f --- /dev/null +++ b/package.json @@ -0,0 +1,22 @@ +{ + "name": "gallery_server_tester", + "version": "1.0.0", + "description": "", + "main": "index.js", + "type": "module", + "scripts": { + "start": "node index.js" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "@tweenjs/tween.js": "^18.6.4", + "colyseus.js": "^0.14.13", + "enquirer": "^2.3.6", + "log-update": "^5.0.1", + "ora": "^6.1.2", + "ramda": "^0.28.0", + "ws": "^8.8.1" + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..9d47e82 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,308 @@ +lockfileVersion: 5.4 + +specifiers: + '@tweenjs/tween.js': ^18.6.4 + colyseus.js: ^0.14.13 + enquirer: ^2.3.6 + log-update: ^5.0.1 + ora: ^6.1.2 + ramda: ^0.28.0 + ws: ^8.8.1 + +dependencies: + '@tweenjs/tween.js': 18.6.4 + colyseus.js: 0.14.13 + enquirer: 2.3.6 + log-update: 5.0.1 + ora: 6.1.2 + ramda: 0.28.0 + ws: 8.8.1 + +packages: + + /@colyseus/schema/1.0.36: + resolution: {integrity: sha512-9LHDELuDCcp/EbZUsgdcekOPINvq+5Dn/Jooq+I2jHymU1zqzzwoqNq9+YYkuvI70OIJ1esPurcMTA2+o7brYg==} + hasBin: true + dev: false + + /@tweenjs/tween.js/18.6.4: + resolution: {integrity: sha512-lB9lMjuqjtuJrx7/kOkqQBtllspPIN+96OvTCeJ2j5FEzinoAXTdAMFnDAQT1KVPRlnYfBrqxtqP66vDM40xxQ==} + dev: false + + /ansi-colors/4.1.3: + resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} + engines: {node: '>=6'} + dev: false + + /ansi-escapes/5.0.0: + resolution: {integrity: sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA==} + engines: {node: '>=12'} + dependencies: + type-fest: 1.4.0 + dev: false + + /ansi-regex/6.0.1: + resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + engines: {node: '>=12'} + dev: false + + /ansi-styles/6.1.0: + resolution: {integrity: sha512-VbqNsoz55SYGczauuup0MFUyXNQviSpFTj1RQtFzmQLk18qbVSpTFFGMT293rmDaQuKCT6InmbuEyUne4mTuxQ==} + engines: {node: '>=12'} + dev: false + + /base64-js/1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + dev: false + + /bl/5.0.0: + resolution: {integrity: sha512-8vxFNZ0pflFfi0WXA3WQXlj6CaMEwsmh63I1CNp0q+wWv8sD0ARx1KovSQd0l2GkwrMIOyedq0EF1FxI+RCZLQ==} + dependencies: + buffer: 6.0.3 + inherits: 2.0.4 + readable-stream: 3.6.0 + dev: false + + /buffer/6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + dev: false + + /chalk/5.0.1: + resolution: {integrity: sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + dev: false + + /cli-cursor/4.0.0: + resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + restore-cursor: 4.0.0 + dev: false + + /cli-spinners/2.7.0: + resolution: {integrity: sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==} + engines: {node: '>=6'} + dev: false + + /clone/1.0.4: + resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} + engines: {node: '>=0.8'} + dev: false + + /colyseus.js/0.14.13: + resolution: {integrity: sha512-2z1jgOfozQ02gLG5RtTHpk9VZur2b7U4KI9NNldjOZmfc2DZeKejdcKchBTwiDcSwwJQQ4SSOfVUhOcBMILDqA==} + engines: {node: '>= 12.x'} + dependencies: + '@colyseus/schema': 1.0.36 + httpie: 2.0.0-next.13 + nanoevents: 5.1.13 + notepack.io: 2.3.0 + tslib: 2.4.0 + dev: false + + /defaults/1.0.3: + resolution: {integrity: sha512-s82itHOnYrN0Ib8r+z7laQz3sdE+4FP3d9Q7VLO7U+KRT+CR0GsWuyHxzdAY82I7cXv0G/twrqomTJLOssO5HA==} + dependencies: + clone: 1.0.4 + dev: false + + /eastasianwidth/0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + dev: false + + /emoji-regex/9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + dev: false + + /enquirer/2.3.6: + resolution: {integrity: sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==} + engines: {node: '>=8.6'} + dependencies: + ansi-colors: 4.1.3 + dev: false + + /httpie/2.0.0-next.13: + resolution: {integrity: sha512-KbKOnq8wt0hVEfteYCSnEsPgzaWxcVc4qZ4OaDU9mVOYLRo3XChjWs3MiuRgFu5y+4JDo7sDKdKzkAn1ljQYFA==} + engines: {node: '>=10'} + dev: false + + /ieee754/1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + dev: false + + /inherits/2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + dev: false + + /is-fullwidth-code-point/4.0.0: + resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} + engines: {node: '>=12'} + dev: false + + /is-interactive/2.0.0: + resolution: {integrity: sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==} + engines: {node: '>=12'} + dev: false + + /is-unicode-supported/1.2.0: + resolution: {integrity: sha512-wH+U77omcRzevfIG8dDhTS0V9zZyweakfD01FULl97+0EHiJTTZtJqxPSkIIo/SDPv/i07k/C9jAPY+jwLLeUQ==} + engines: {node: '>=12'} + dev: false + + /log-symbols/5.1.0: + resolution: {integrity: sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA==} + engines: {node: '>=12'} + dependencies: + chalk: 5.0.1 + is-unicode-supported: 1.2.0 + dev: false + + /log-update/5.0.1: + resolution: {integrity: sha512-5UtUDQ/6edw4ofyljDNcOVJQ4c7OjDro4h3y8e1GQL5iYElYclVHJ3zeWchylvMaKnDbDilC8irOVyexnA/Slw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + ansi-escapes: 5.0.0 + cli-cursor: 4.0.0 + slice-ansi: 5.0.0 + strip-ansi: 7.0.1 + wrap-ansi: 8.0.1 + dev: false + + /mimic-fn/2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + dev: false + + /nanoevents/5.1.13: + resolution: {integrity: sha512-JFAeG9fp0QZnRoESHjkbVFbZ9BkOXkkagUVwZVo/pkSX+Fq1VKlY+5og/8X9CYc6C7vje/CV+bwJ5M2X0+IY9Q==} + engines: {node: '>=6.0.0'} + dev: false + + /notepack.io/2.3.0: + resolution: {integrity: sha512-9RiFDxeydHsWOqdthRUck2Kd4UW2NzVd2xxOulZiQ9mvge6ElsHXLpwD3HEJyql6sFEnEn/eMO7HSdS0M5mWkA==} + dev: false + + /onetime/5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + dependencies: + mimic-fn: 2.1.0 + dev: false + + /ora/6.1.2: + resolution: {integrity: sha512-EJQ3NiP5Xo94wJXIzAyOtSb0QEIAUu7m8t6UZ9krbz0vAJqr92JpcK/lEXg91q6B9pEGqrykkd2EQplnifDSBw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + bl: 5.0.0 + chalk: 5.0.1 + cli-cursor: 4.0.0 + cli-spinners: 2.7.0 + is-interactive: 2.0.0 + is-unicode-supported: 1.2.0 + log-symbols: 5.1.0 + strip-ansi: 7.0.1 + wcwidth: 1.0.1 + dev: false + + /ramda/0.28.0: + resolution: {integrity: sha512-9QnLuG/kPVgWvMQ4aODhsBUFKOUmnbUnsSXACv+NCQZcHbeb+v8Lodp8OVxtRULN1/xOyYLLaL6npE6dMq5QTA==} + dev: false + + /readable-stream/3.6.0: + resolution: {integrity: sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==} + engines: {node: '>= 6'} + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + dev: false + + /restore-cursor/4.0.0: + resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + onetime: 5.1.2 + signal-exit: 3.0.7 + dev: false + + /safe-buffer/5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + dev: false + + /signal-exit/3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + dev: false + + /slice-ansi/5.0.0: + resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} + engines: {node: '>=12'} + dependencies: + ansi-styles: 6.1.0 + is-fullwidth-code-point: 4.0.0 + dev: false + + /string-width/5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.0.1 + dev: false + + /string_decoder/1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + dependencies: + safe-buffer: 5.2.1 + dev: false + + /strip-ansi/7.0.1: + resolution: {integrity: sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==} + engines: {node: '>=12'} + dependencies: + ansi-regex: 6.0.1 + dev: false + + /tslib/2.4.0: + resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==} + dev: false + + /type-fest/1.4.0: + resolution: {integrity: sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==} + engines: {node: '>=10'} + dev: false + + /util-deprecate/1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + dev: false + + /wcwidth/1.0.1: + resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} + dependencies: + defaults: 1.0.3 + dev: false + + /wrap-ansi/8.0.1: + resolution: {integrity: sha512-QFF+ufAqhoYHvoHdajT/Po7KoXVBPXS2bgjIam5isfWJPfIOnQZ50JtUiVvCv/sjgacf3yRrt2ZKUZ/V4itN4g==} + engines: {node: '>=12'} + dependencies: + ansi-styles: 6.1.0 + string-width: 5.1.2 + strip-ansi: 7.0.1 + dev: false + + /ws/8.8.1: + resolution: {integrity: sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dev: false diff --git a/received-packages.js b/received-packages.js new file mode 100644 index 0000000..d294cf6 --- /dev/null +++ b/received-packages.js @@ -0,0 +1,10 @@ +let lastReceivedAt = new Date(); +export let rps = 0; +export let packageCounts = 0; + +export const markReceive = () => { + const now = new Date(); + rps = (1000 / (now.getTime() - lastReceivedAt.getTime())).toFixed(2); + lastReceivedAt = now; + packageCounts++; +} \ No newline at end of file diff --git a/test-group.js b/test-group.js new file mode 100644 index 0000000..efbbd54 --- /dev/null +++ b/test-group.js @@ -0,0 +1,37 @@ +import { splitEvery } from 'ramda'; +import { parentPort } from 'worker_threads'; +import { Client } from './client.js'; + +const clients = []; + +parentPort.on('message', message => { + switch(message.type) { + case 'testOnce': + clients.forEach(worker => { + if (worker.index < message.limit) { + worker.testOnce(); + } + }); + break; + case 'generateWorkers': + clients.splice( + 0, + clients.length, + ...new Array(message.end - message.start).fill(undefined).map((_, i) => new Client(i + message.start)), + ); + parentPort.postMessage({ type: 'workersGenerated' }); + break; + case 'joinRoom': + (async () => { + for (const group of splitEvery(4)(clients)) { + await Promise.all(group.map(async client => { + await client.joinRoom(); + parentPort.postMessage({ type: 'oneWorkerJoined', index: client.index }); + })); + } + parentPort.postMessage({ type: 'workersJoined' }); + })().catch(err => { + parentPort.postMessage({ type: 'joinRoomFailed', error: err }); + }) + } +}); \ No newline at end of file