-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow passing in a custom createConnection
function
#1944
Comments
You can use the import { Agent } from 'https';
import { WebSocket } from 'ws';
import { connect } from 'tls';
const agent = new Agent();
agent.createConnection = function (options) {
return connect(options);
};
const ws = new WebSocket('wss://ws.ifelse.io', { agent });
ws.on('open', function () {
console.log('open');
}); |
Ah, cool, I didn't realize that that was also an option on the agent. I'll try that out and close this issue if it works. |
It turns out that it's not enough to just return the stream, it also needs to be wrapped to look at least a bit like a network socket. Here's the conversion function, with TypeScript typings, in case anyone else stumbles upon the need for this: import { Socket } from 'net';
import { Duplex } from 'stream';
export const makeNetSocketFromDuplexStream = (stream: Duplex) => {
const cast = stream as Socket;
const patched: { [K in keyof Omit<Socket, keyof Duplex>]: Socket[K] } = {
bufferSize: 0,
bytesRead: 0,
bytesWritten: 0,
connecting: false,
localAddress: '127.0.0.1',
localPort: 1,
remoteAddress: '127.0.0.1',
remoteFamily: 'tcp',
remotePort: 1,
address: () => ({ address: '127.0.0.1', family: 'tcp', port: 1 }),
unref: () => cast,
ref: () => cast,
connect: (_port: unknown, _host?: unknown, connectionListener?: () => void) => {
if (connectionListener) {
setImmediate(connectionListener);
}
return cast;
},
setKeepAlive: () => cast,
setNoDelay: () => cast,
setTimeout: (_timeout: number, callback?: () => void) => {
callback?.();
return cast;
},
};
return Object.assign(stream, patched) as Socket;
}; |
If the opening handshake can be skipped, then a generic duplex stream can be used by calling the "private" function noop() {}
const duplex = new Duplex({
read() {},
write() {}
});
duplex.setTimeout = noop;
duplex.setNoDelay = noop;
const ws = new WebSocket(null);
ws.setSocket(duplex, Buffer.alloc(0));
// ... Anyway this is not recommended as it makes use of a private API. |
Description
We have a kind of exotic use case where we want to instantiate a websocket off an existing stream that's not from an HTTP or unix socket source. Currently the
createConnection
method is hardcoded to either create a TLS or standard net connection:ws/lib/websocket.js
Line 654 in f871195
I suggest allowing a custom
createConnection
function to be passed in the websocket options and, if present, it should take precedence over the existing default logic.I'm happy to put together a PR for this if it's something you'd accept 🙂
ws version
8.2.2
Node.js Version
v16.6.1
System
System:
OS: Windows 10 10.0.19043
CPU: (24) x64 AMD Ryzen 9 5900X 12-Core Processor
Memory: 23.22 GB / 63.89 GB
Expected result
N/A
Actual result
N/A
Attachments
No response
The text was updated successfully, but these errors were encountered: