Skip to content

Commit 443d4fc

Browse files
Chenyu Yangrichardlau
Chenyu Yang
authored andcommitted
benchmark: add undici websocket benchmark
Refs: nodejs/performance#114 PR-URL: #50586 Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Matthew Aitken <[email protected]>
1 parent de65cad commit 443d4fc

File tree

2 files changed

+109
-0
lines changed

2 files changed

+109
-0
lines changed

benchmark/websocket/simple.js

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
'use strict';
2+
3+
const common = require('../common.js');
4+
const crypto = require('crypto');
5+
const http = require('http');
6+
const { WebSocket } = require('../../deps/undici/undici');
7+
8+
const GUID = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
9+
10+
const configs = {
11+
size: [64, 16 * 1024, 128 * 1024, 1024 * 1024],
12+
useBinary: ['true', 'false'],
13+
roundtrips: [5000, 1000, 100],
14+
};
15+
16+
const bench = common.createBenchmark(main, configs);
17+
18+
function createFrame(data, opcode) {
19+
let infoLength = 2;
20+
let payloadLength = data.length;
21+
22+
if (payloadLength >= 65536) {
23+
infoLength += 8;
24+
payloadLength = 127;
25+
} else if (payloadLength > 125) {
26+
infoLength += 2;
27+
payloadLength = 126;
28+
}
29+
30+
const info = Buffer.alloc(infoLength);
31+
32+
info[0] = opcode | 0x80;
33+
info[1] = payloadLength;
34+
35+
if (payloadLength === 126) {
36+
info.writeUInt16BE(data.length, 2);
37+
} else if (payloadLength === 127) {
38+
info[2] = info[3] = 0;
39+
info.writeUIntBE(data.length, 4, 6);
40+
}
41+
42+
return Buffer.concat([info, data]);
43+
}
44+
45+
function main(conf) {
46+
const frame = createFrame(Buffer.alloc(conf.size).fill('.'), conf.useBinary === 'true' ? 2 : 1);
47+
const server = http.createServer();
48+
server.on('upgrade', (req, socket) => {
49+
const key = crypto
50+
.createHash('sha1')
51+
.update(req.headers['sec-websocket-key'] + GUID)
52+
.digest('base64');
53+
54+
let bytesReceived = 0;
55+
let roundtrip = 0;
56+
57+
socket.on('data', function onData(chunk) {
58+
bytesReceived += chunk.length;
59+
60+
if (bytesReceived === frame.length + 4) { // +4 for the mask.
61+
// Message completely received.
62+
bytesReceived = 0;
63+
64+
if (++roundtrip === conf.roundtrips) {
65+
socket.removeListener('data', onData);
66+
socket.resume();
67+
socket.end();
68+
server.close();
69+
70+
bench.end(conf.roundtrips);
71+
} else {
72+
socket.write(frame);
73+
}
74+
}
75+
});
76+
77+
socket.write(
78+
[
79+
'HTTP/1.1 101 Switching Protocols',
80+
'Upgrade: websocket',
81+
'Connection: Upgrade',
82+
`Sec-WebSocket-Accept: ${key}`,
83+
'\r\n',
84+
].join('\r\n'),
85+
);
86+
87+
socket.write(frame);
88+
});
89+
90+
server.listen(0, () => {
91+
const ws = new WebSocket(`ws://localhost:${server.address().port}`);
92+
ws.addEventListener('open', () => {
93+
bench.start();
94+
});
95+
96+
ws.addEventListener('message', (event) => {
97+
ws.send(event.data);
98+
});
99+
});
100+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
if (!common.enoughTestMem)
5+
common.skip('Insufficient memory for Websocket benchmark test');
6+
7+
const runBenchmark = require('../common/benchmark');
8+
9+
runBenchmark('websocket', { NODEJS_BENCHMARK_ZERO_ALLOWED: 1 });

0 commit comments

Comments
 (0)