reconnecting-websocket
reconnecting-websocket copied to clipboard
WebSocket creation callback
Hello,
Currently, the only way to supply non-default WebSocket implementation (e.g. 'ws' in Node.js) - is to pass a custom constructor via options. This has a limitation that a constructor must comply with one of the 2 variants:
new WebSocket(url, this._protocols)
new WebSocket(url)
However, 'ws' has a 3rd very important variant:
constructor(address: string, protocols?: string | string[], options?: WebSocket.ClientOptions)
https://github.com/websockets/ws/blob/88d0345997ea14b262519c7d5b5baaf6f9d78035/lib/websocket.js#L43
Where options is something like this:
interface ClientOptions {
protocol?: string;
handshakeTimeout?: number;
perMessageDeflate?: boolean | PerMessageDeflateOptions;
localAddress?: string;
protocolVersion?: number;
headers?: { [key: string]: string };
origin?: string;
agent?: http.Agent;
host?: string;
family?: number;
checkServerIdentity?(servername: string, cert: CertMeta): boolean;
rejectUnauthorized?: boolean;
passphrase?: string;
ciphers?: string;
cert?: CertMeta;
key?: CertMeta;
pfx?: string | Buffer;
ca?: CertMeta;
maxPayload?: number;
}
Note that there are some super-important options like TLS parameters etc. Currently, the only way to solve this - is to implement a custom ws-derived class where one had hard-code relevant parameters. But what if I can't hard-code them and I need to pass different values from the caller? There seems to be no way to do it.
A possible solution is to add ability to pass a "WebSocket creation callback", i.e. a function which will return a WebSocket-resembling object. This way, the construction work moves to the caller allowing creation of WebSocket object in any way desirable
In other words, instead of this line: https://github.com/pladaria/reconnecting-websocket/blob/05a2f7cb0e31f15dff5ff35ad53d07b1bec5e197/reconnecting-websocket.ts#L382-L384
write something like: (assuming createWebSocket is a function passed in options)
this._ws = createWebSocket(url, this_protocols, options)
Thank you.
Yeah a websocket factory would be nice. I think that's more useful than a url factory
You can do it like this 😉
function createWebSocketClass(options) {
return class extends WebSocket {
constructor(url, protocols) {
super(url, protocols, options)
}
}
}
const token = '123456'
const rws = new ReconnectingWebSocket(url, '', {
WebSocket: createWebSocketClass({
headers: {
Authorization: `Bearer ${token}`,
},
})
})
@pladaria should I add this to the documentation?
Thanks @alexsegura. Indeed, this nice idea works. Though I would still prefer an explicit createWebSocket
method in options, rather than this somewhat "hacky" method. It would also eliminate the need to document a (admittedly clever) workaround, because it would make this common usage more obvious.