In the code below, I try to
- Connect a WebSocket client to a WebSocket server
- Connect the socket client to a socket server with different orders.
In the promise1, the order of connection is:
- Connect a WebSocket client to a WebSocket server.
- Connect socket client to a socket server.
And the
promise1never resolved.
In the promise2, the order of connection is:
- Connect socket client to a socket server.
- Connect a WebSocket client to a WebSocket server.
And the
promise2is resolved.
import * as net from 'node:net';
import fs from 'fs';
import WebSocket, { WebSocketServer } from 'ws';
const testWSPort = Math.round(Math.random() * 10000);
const testSocketPath = `/tmp/test-${testWSPort}.sock`;
(async () => {
if (fs.existsSync(testSocketPath)) {
fs.unlinkSync(testSocketPath);
}
await startWSS({ port: testWSPort });
(await startUnixDomainSocketServer(testSocketPath)).server;
console.time('wsClient');
const wsClient = new WebSocket(`ws://localhost:${testWSPort}`);
console.time('socketClient');
const socketClient = net.createConnection({ path: testSocketPath });
const promise1 = new Promise<void>(async (resolve, reject) => {
await new Promise<void>((done) => {
wsClient.on('open', () => {
done();
});
wsClient.on('error', done);
});
await new Promise<void>((done) => {
socketClient.on('connect', done);
socketClient.on('error', done);
socketClient.on('timeout', done);
});
resolve();
});
const promise2 = new Promise<void>(async (resolve) => {
await new Promise<void>((done) => {
socketClient.on('connect', done);
socketClient.on('error', done);
socketClient.on('timeout', done);
});
await new Promise<void>((done) => {
wsClient.on('open', done);
wsClient.on('error', done);
});
resolve();
});
const promise3 = Promise.all([
new Promise<void>((done) => {
socketClient.on('connect', () => {
console.timeEnd('socketClient');
done();
});
socketClient.on('error', done);
socketClient.on('timeout', done);
}),
new Promise<void>((done) => {
wsClient.on('open', () => {
console.timeEnd('wsClient');
done();
});
wsClient.on('error', done);
}),
]);
promise1.then(() => {
console.log('Why does this line never executed?');
});
promise2.then(() => {
console.log('But this line executed!');
});
promise3.then(() => {
console.log('This line also executed');
});
})();
function startWSS({ port }: { port: number }) {
const wss = new WebSocketServer({ port });
wss.on('connection', function connection(ws) {
ws.on('error', console.error);
});
return new Promise<WebSocketServer>((resolve, reject) => {
wss.on('listening', () => {
resolve(wss);
});
wss.on('error', reject);
});
}
function startUnixDomainSocketServer(
socketPath: string
): Promise<{ server: net.Server }> {
return new Promise((resolve, reject) => {
const server = new net.Server();
server.listen(socketPath, () => {
resolve({ server });
});
server.on('error', (err) => {
reject(err);
});
});
}
My questions
Why is promise1 never resolved?
Why change the position of this order cause this difference?
You can try this code here: https://stackblitz.com/edit/stackblitz-starters-ervgkg?file=index.ts
What I have tried
I think this is a problem related to node.js event loop. I read this article, but I still can't figure out the reason.