There are a lot of interesting answers that do the job, however they mostly seem unclean, that is if you don't mind mutating the ws object. I did it this way because I'm using TypeScript and you can't arbitrarily add properties to objects.
import WebSocket from 'ws'
declare module 'ws' {
interface WebSocket {
id: any
key: string
}
}
The id doesn't have to be type any can be number or string depending on how you ID your connections. I haven't flushed out the system yet but for now when a connection is made, I just assign a random number.
const socketConnection = (socket: WebSocket.WebSocket): void => {
socket.id = Math.random()
console.log(socket.id)
const msg = JSON.stringify({ res: `[open] Welcome to the WebSocket server!` })
socket.send(msg)
}
This can be modified at any point so once I authenticate the connection I plan on assigning a relative ID here and might even add in a key property if I want to do some more fancy stuff.
How this works is explained in the Module Augmentation section of the documentation.
TypeScript: Module Augmentation
You can check that it's still assigned by looking over multiple messages in the onmessage event.
const socketMessage = (socket: WebSocket.WebSocket): void => {
socket.on('message', async (message: WebSocket.RawData) => {
console.log(socket.id)
console.log(socket.key)
})
}
Oh and a note, I made this module declaration in the document where I setup my socket. But the modification does populate across documents. For example in the AuthController I started prototyping I use it this way.
export default class AuthController {
public static connections: DLinkedList = new DLinkedList()
static async validate(request: { id: string, socket: WebSocket.WebSocket }): Promise<void> {
console.log('test', request.socket.id)
this.connections.add(request.socket, request.id)
request.socket.send(JSON.stringify({ res: true }))
console.log(this.connections.size())
}
static getSocket(id: string): WebSocket.WebSocket {
return this.connections.getAtKey(id).data
}
static removeSocket(socket: WebSocket.WebSocket) {
}
}
You can also do this in pure JS just by directly modifying the WebSocket object prototype. Some of the answers here talk about it. I haven't done it myself but the principle is similar.
Add a method to an existing class in typescript?
Hope this is useful.