feat(cli): add benchmark connections and register command

pull/90/head
moonrailgun 2 years ago
parent 48145a01ee
commit 9524502d70

@ -60,6 +60,8 @@
"pretty-ms": "7.0.1", "pretty-ms": "7.0.1",
"react": "18.2.0", "react": "18.2.0",
"rimraf": "^3.0.2", "rimraf": "^3.0.2",
"socket.io-client": "^4.6.2",
"socket.io-msgpack-parser": "^3.0.2",
"spinnies": "^0.5.1", "spinnies": "^0.5.1",
"tailchat-server-sdk": "^0.0.12", "tailchat-server-sdk": "^0.0.12",
"update-notifier": "5.1.0", "update-notifier": "5.1.0",

@ -0,0 +1,73 @@
import { CommandModule } from 'yargs';
import { io, Socket } from 'socket.io-client';
import msgpackParser from 'socket.io-msgpack-parser';
import fs from 'fs-extra';
const CLIENT_CREATION_INTERVAL_IN_MS = 5;
export const benchmarkConnectionsCommand: CommandModule = {
command: 'connections',
describe: 'Test Tailchat Connections',
builder: (yargs) =>
yargs
.option('url', {
describe: 'Url',
demandOption: true,
type: 'string',
})
.option('accountPath', {
describe: 'Account Token Path',
demandOption: true,
type: 'string',
}),
async handler(args) {
const account = await fs.readFile(args.accountPath as string, {
encoding: 'utf8',
});
createClients(
args.url as string,
account.split('\n').map((s) => s.trim())
);
},
};
async function createClients(url: string, accountTokens: string[]) {
const maxCount = accountTokens.length;
for (const token of accountTokens) {
await sleep(CLIENT_CREATION_INTERVAL_IN_MS);
await createClient(url, token);
}
console.log(`${maxCount} clients has been create.`);
}
function createClient(url: string, token: string): Promise<Socket> {
return new Promise((resolve, reject) => {
const socket = io(url, {
transports: ['websocket'],
auth: {
token,
},
forceNew: true,
parser: msgpackParser,
});
socket.once('connect', () => {
// 连接成功
resolve(socket);
});
socket.once('error', () => {
reject();
});
socket.on('disconnect', (reason) => {
console.log(`disconnect due to ${reason}`);
});
});
}
export function sleep(milliseconds: number): Promise<void> {
return new Promise((resolve) => {
setTimeout(resolve, milliseconds);
});
}

@ -1,11 +1,18 @@
import { CommandModule } from 'yargs'; import { CommandModule } from 'yargs';
import { benchMessageCommand } from './message'; import { benchmarkConnectionsCommand } from './connections';
import { benchmarkMessageCommand } from './message';
import { benchmarkRegisterCommand } from './register';
// https://docs.docker.com/engine/api/v1.41/ // https://docs.docker.com/engine/api/v1.41/
export const benchmarkCommand: CommandModule = { export const benchmarkCommand: CommandModule = {
command: 'benchmark', command: 'benchmark',
describe: 'Tailchat Benchmark Test', describe: 'Tailchat Benchmark Test',
builder: (yargs) => yargs.command(benchMessageCommand).demandCommand(), builder: (yargs) =>
yargs
.command(benchmarkMessageCommand)
.command(benchmarkConnectionsCommand)
.command(benchmarkRegisterCommand)
.demandCommand(),
handler(args) {}, handler(args) {},
}; };

@ -10,7 +10,7 @@ import ora from 'ora';
import prettyMs from 'pretty-ms'; import prettyMs from 'pretty-ms';
import filesize from 'filesize'; import filesize from 'filesize';
export const benchMessageCommand: CommandModule = { export const benchmarkMessageCommand: CommandModule = {
command: 'message', command: 'message',
describe: describe:
'Stress testing through Tailchat network requests (suitable for pure business testing)', 'Stress testing through Tailchat network requests (suitable for pure business testing)',

@ -0,0 +1,55 @@
import { CommandModule } from 'yargs';
import fs from 'fs-extra';
import got from 'got';
export const benchmarkRegisterCommand: CommandModule = {
command: 'register',
describe: 'Create Tailchat temp account and output token',
builder: (yargs) =>
yargs
.option('url', {
describe: 'Backend Url',
demandOption: true,
type: 'string',
})
.option('accountPath', {
describe: 'Account Token Path',
demandOption: true,
type: 'string',
default: './accounts',
})
.option('count', {
describe: 'Register Count',
demandOption: true,
type: 'number',
default: 100,
}),
async handler(args) {
const count = args.count as number;
const tokens: string[] = [];
for (let i = 0; i < count; i++) {
const token = await registerTemporaryAccount(
args.url as string,
`benchUser-${i}`
);
tokens.push(token);
}
await fs.writeFile(args.accountPath as string, tokens.join('\n'));
},
};
async function registerTemporaryAccount(
url: string,
nickname: string
): Promise<string> {
const res = await got
.post(`${url}/api/user/createTemporaryUser`, {
json: {
nickname,
},
})
.json<{ token: string }>();
return res.token;
}

@ -183,6 +183,12 @@ importers:
rimraf: rimraf:
specifier: ^3.0.2 specifier: ^3.0.2
version: 3.0.2 version: 3.0.2
socket.io-client:
specifier: ^4.6.2
version: 4.6.2
socket.io-msgpack-parser:
specifier: ^3.0.2
version: 3.0.2
spinnies: spinnies:
specifier: ^0.5.1 specifier: ^0.5.1
version: 0.5.1 version: 0.5.1
@ -560,7 +566,7 @@ importers:
version: 0.32.11 version: 0.32.11
zustand: zustand:
specifier: ^4.3.6 specifier: ^4.3.6
version: 4.3.6(immer@9.0.15)(react@18.2.0) version: 4.3.6(immer@9.0.21)(react@18.2.0)
devDependencies: devDependencies:
'@types/crc': '@types/crc':
specifier: ^3.4.0 specifier: ^3.4.0
@ -1828,7 +1834,7 @@ importers:
version: 5.3.6(react-dom@18.2.0)(react-is@18.2.0)(react@18.2.0) version: 5.3.6(react-dom@18.2.0)(react-is@18.2.0)(react@18.2.0)
zustand: zustand:
specifier: ^4.3.6 specifier: ^4.3.6
version: 4.3.6(immer@9.0.15)(react@18.2.0) version: 4.3.6(immer@9.0.21)(react@18.2.0)
server/plugins/com.msgbyte.getui: server/plugins/com.msgbyte.getui:
dependencies: dependencies:
@ -2006,7 +2012,7 @@ importers:
version: 5.3.6(react-dom@18.2.0)(react-is@18.2.0)(react@18.2.0) version: 5.3.6(react-dom@18.2.0)(react-is@18.2.0)(react@18.2.0)
zustand: zustand:
specifier: ^4.3.6 specifier: ^4.3.6
version: 4.3.6(immer@9.0.15)(react@18.2.0) version: 4.3.6(immer@9.0.21)(react@18.2.0)
server/plugins/com.msgbyte.welcome: server/plugins/com.msgbyte.welcome:
dependencies: dependencies:
@ -18478,7 +18484,7 @@ packages:
dependencies: dependencies:
'@socket.io/component-emitter': 3.1.0 '@socket.io/component-emitter': 3.1.0
debug: 4.3.4(supports-color@9.2.2) debug: 4.3.4(supports-color@9.2.2)
engine.io-parser: 5.0.4 engine.io-parser: 5.0.6
ws: 8.2.3 ws: 8.2.3
xmlhttprequest-ssl: 2.0.0 xmlhttprequest-ssl: 2.0.0
transitivePeerDependencies: transitivePeerDependencies:
@ -18500,14 +18506,9 @@ packages:
- utf-8-validate - utf-8-validate
dev: false dev: false
/engine.io-parser@5.0.4:
resolution: {integrity: sha512-+nVFp+5z1E3HcToEnO7ZIj3g+3k9389DvWtvJZz0T6/eOCPIyyxehFcedoYrZQrp0LgQbD9pPXhpMBKMd5QURg==}
engines: {node: '>=10.0.0'}
/engine.io-parser@5.0.6: /engine.io-parser@5.0.6:
resolution: {integrity: sha512-tjuoZDMAdEhVnSFleYPCtdL2GXwVTGtNjoeJd9IhIG3C1xs9uwxqRNEu5WpnDZCaozwVlK/nuQhpodhXSIMaxw==} resolution: {integrity: sha512-tjuoZDMAdEhVnSFleYPCtdL2GXwVTGtNjoeJd9IhIG3C1xs9uwxqRNEu5WpnDZCaozwVlK/nuQhpodhXSIMaxw==}
engines: {node: '>=10.0.0'} engines: {node: '>=10.0.0'}
dev: false
/engine.io@6.2.0: /engine.io@6.2.0:
resolution: {integrity: sha512-4KzwW3F3bk+KlzSOY57fj/Jx6LyRQ1nbcyIadehl+AnXjKT7gDO0ORdRi/84ixvMKTym6ZKuxvbzN62HDDU1Lg==} resolution: {integrity: sha512-4KzwW3F3bk+KlzSOY57fj/Jx6LyRQ1nbcyIadehl+AnXjKT7gDO0ORdRi/84ixvMKTym6ZKuxvbzN62HDDU1Lg==}
@ -18521,7 +18522,7 @@ packages:
cookie: 0.4.2 cookie: 0.4.2
cors: 2.8.5 cors: 2.8.5
debug: 4.3.4(supports-color@9.2.2) debug: 4.3.4(supports-color@9.2.2)
engine.io-parser: 5.0.4 engine.io-parser: 5.0.6
ws: 8.2.3 ws: 8.2.3
transitivePeerDependencies: transitivePeerDependencies:
- bufferutil - bufferutil
@ -21884,10 +21885,10 @@ packages:
/immer@9.0.15: /immer@9.0.15:
resolution: {integrity: sha512-2eB/sswms9AEUSkOm4SbV5Y7Vmt/bKRwByd52jfLkW4OLYeaTP3EEiJ9agqU0O/tq6Dk62Zfj+TJSqfm1rLVGQ==} resolution: {integrity: sha512-2eB/sswms9AEUSkOm4SbV5Y7Vmt/bKRwByd52jfLkW4OLYeaTP3EEiJ9agqU0O/tq6Dk62Zfj+TJSqfm1rLVGQ==}
dev: false
/immer@9.0.21: /immer@9.0.21:
resolution: {integrity: sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==} resolution: {integrity: sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==}
dev: false
/import-fresh@2.0.0: /import-fresh@2.0.0:
resolution: {integrity: sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==} resolution: {integrity: sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==}
@ -32435,6 +32436,20 @@ packages:
- utf-8-validate - utf-8-validate
dev: false dev: false
/socket.io-client@4.6.2:
resolution: {integrity: sha512-OwWrMbbA8wSqhBAR0yoPK6EdQLERQAYjXb3A0zLpgxfM1ZGLKoxHx8gVmCHA6pcclRX5oA/zvQf7bghAS11jRA==}
engines: {node: '>=10.0.0'}
dependencies:
'@socket.io/component-emitter': 3.1.0
debug: 4.3.4(supports-color@9.2.2)
engine.io-client: 6.4.0
socket.io-parser: 4.2.4
transitivePeerDependencies:
- bufferutil
- supports-color
- utf-8-validate
dev: false
/socket.io-msgpack-parser@3.0.2: /socket.io-msgpack-parser@3.0.2:
resolution: {integrity: sha512-1e76bJ1PCKi9H+JiYk+S29PBJvknHjQWM7Mtj0hjF2KxDA6b6rQxv3rTsnwBoz/haZOhlCDIMQvPATbqYeuMxg==} resolution: {integrity: sha512-1e76bJ1PCKi9H+JiYk+S29PBJvknHjQWM7Mtj0hjF2KxDA6b6rQxv3rTsnwBoz/haZOhlCDIMQvPATbqYeuMxg==}
dependencies: dependencies:
@ -32472,6 +32487,16 @@ packages:
- supports-color - supports-color
dev: false dev: false
/socket.io-parser@4.2.4:
resolution: {integrity: sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==}
engines: {node: '>=10.0.0'}
dependencies:
'@socket.io/component-emitter': 3.1.0
debug: 4.3.4(supports-color@9.2.2)
transitivePeerDependencies:
- supports-color
dev: false
/socket.io@4.5.1: /socket.io@4.5.1:
resolution: {integrity: sha512-0y9pnIso5a9i+lJmsCdtmTTgJFFSvNQKDnPQRz28mGNnxbmqYg2QPtJTLFxhymFZhAIn50eHAKzJeiNaKr+yUQ==} resolution: {integrity: sha512-0y9pnIso5a9i+lJmsCdtmTTgJFFSvNQKDnPQRz28mGNnxbmqYg2QPtJTLFxhymFZhAIn50eHAKzJeiNaKr+yUQ==}
engines: {node: '>=10.0.0'} engines: {node: '>=10.0.0'}
@ -33487,7 +33512,7 @@ packages:
hark: 1.2.3 hark: 1.2.3
lodash: 4.17.21 lodash: 4.17.21
mediasoup-client: 3.6.57 mediasoup-client: 3.6.57
socket.io-client: 4.5.1 socket.io-client: 4.6.2
transitivePeerDependencies: transitivePeerDependencies:
- bufferutil - bufferutil
- supports-color - supports-color
@ -36676,6 +36701,7 @@ packages:
immer: 9.0.15 immer: 9.0.15
react: 18.2.0 react: 18.2.0
use-sync-external-store: 1.2.0(react@18.2.0) use-sync-external-store: 1.2.0(react@18.2.0)
dev: false
/zustand@4.3.6(immer@9.0.21)(react@18.2.0): /zustand@4.3.6(immer@9.0.21)(react@18.2.0):
resolution: {integrity: sha512-6J5zDxjxLE+yukC2XZWf/IyWVKnXT9b9HUv09VJ/bwGCpKNcaTqp7Ws28Xr8jnbvnZcdRaidztAPsXFBIqufiw==} resolution: {integrity: sha512-6J5zDxjxLE+yukC2XZWf/IyWVKnXT9b9HUv09VJ/bwGCpKNcaTqp7Ws28Xr8jnbvnZcdRaidztAPsXFBIqufiw==}
@ -36692,7 +36718,6 @@ packages:
immer: 9.0.21 immer: 9.0.21
react: 18.2.0 react: 18.2.0
use-sync-external-store: 1.2.0(react@18.2.0) use-sync-external-store: 1.2.0(react@18.2.0)
dev: false
/zwitch@1.0.5: /zwitch@1.0.5:
resolution: {integrity: sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==} resolution: {integrity: sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==}

Loading…
Cancel
Save