-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathindex.js
More file actions
129 lines (119 loc) · 4.33 KB
/
index.js
File metadata and controls
129 lines (119 loc) · 4.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
const { createConnection } = require('node:net');
const { cpus } = require('node:os');
const express = require('express');
const { createServer } = require('http');
const { WebSocketServer } = require('ws');
const { Launcher } = require('chrome-launcher');
const CDP = require('chrome-remote-interface');
Launcher.prototype.isDebuggerReady = function () {
return new Promise((resolve, reject) => {
const host = '127.0.0.1';
const workerId = this.workerId;
const port = this.port;
const client = createConnection({ port: this.port, host, timeout: 5000 });
client.once('error', (err) => {
// console.log(`[worker ${workerId}] connection to chrome debugger protocol on ${port} failed: ${err}`);
this.cleanup(client);
reject(err);
});
client.once('timeout', () => {
console.log(`[worker ${workerId}] connection to chrome debugger protocol on ${port} timed out`);
this.cleanup(client);
const message = `Chrome instance is not available on ${host}:${this.port}`;
reject({ message });
});
client.once('connect', () => {
console.log(`[worker ${workerId}] connection to chrome debugger protocol on ${port} succeeded`);
this.cleanup(client);
resolve(undefined);
});
});
};
const app = express()
app.use('/sandbox:id.html', (req, res) => {
res.send(`
<!DOCTYPE html>
<html>
<body>
<h1>WebSocket Test${req.params.id}</h1>
<script>
function start() {
const ws = new WebSocket('ws://' + window.location.host);
ws.onopen = () => {
console.log('WebSocket connected!');
ws.send('hello from client: ' + ${req.params.id});
};
ws.onmessage = (event) => {
console.log('message from server:', event.data);
};
}
</script>
</body>
</html>
`);
});
const server = createServer(app);
const wss = new WebSocketServer({ server });
wss.on('connection', (ws) => {
// console.log('new WebSocket connection');
ws.send('hello');
ws.on('message', (message) => {
console.log('wss:received:', message.toString());
ws.send(`you said: ${message}`);
});
});
const PORT = 3000;
server.listen(PORT, () => {
console.log(`server is running on http://localhost:${PORT}`);
});
const chromeFlags = ['--headless', '--disable-gpu', '--deterministic-fetch'];
async function main(count) {
const tasks = [];
for (let i = 0; i < count; i++) {
tasks.push(new Promise(async (resolve) => {
try {
const chrome = new Launcher({ chromeFlags, logLevel: 'error' });
chrome.workerId = i;
await chrome.launch();
console.log(`started chrome instance [${i}]`);
const options = { host: '127.0.0.1', port: chrome.port, url: 'about:blank' };
const tab = await CDP.New(options);
console.log(`created tab for chrome instance [${i}]`);
const client = await CDP({
host: options.host,
port: options.port,
tab,
target: tab.id,
});
console.log(`connected to tab for chrome instance [${i}]`);
const { Page, Network } = client;
await Promise.all([
Page.enable(),
Network.enable(),
]);
console.log(`enabled page/network for chrome instance [${i}]`);
Network.requestIntercepted(({ interceptionId, request }) =>
Network.continueInterceptedRequest({
interceptionId,
url: request.url,
}).catch(() => { }),
);
await client.send('Network.setRequestInterception', { patterns: [{ urlPattern: '*' }] });
console.log(`set request interception for chrome instance [${i}]`);
await Page.navigate({ url: `http://localhost:3000/sandbox${i}.html` });
console.log(`navigated to sandbox${i}.html for chrome instance [${i}]`);
await Page.loadEventFired();
console.log(`load event fired for chrome instance [${i}]`);
await client.Runtime.evaluate({ expression: 'start();' });
console.log(`started script for chrome instance [${i}]`);
resolve();
} catch (err) {
console.error(`error in chrome instance [${i}]:`, err);
}
}));
}
await Promise.all(tasks);
await new Promise((resolve) => setTimeout(resolve, 3000));
console.log('all tasks completed');
}
main(cpus().length - 2);