How to establish websocket connection?

Hi There

I am planning on creating my own two nodes one for subscribing to certain events and another one for sending some actions. These happen both over the same websocket connection. So I thought about doing this in a configuration node which establishes the websocket connection and also gets a new token automatically as soon as the current one expires. I saw the "websocket-in" node which would almost fit my need except I need some username / password on top. What would be the best way to reuse the code? Copying it from the existing websocket-in node into my own custom node? How can I automatically refresh bearer tokens before they expire?

Thank you and have a nice weekend

You should think about how secure you want this. For starters, you MUST have https/wss configured before using user ids and passwords.

Then you need to understand that websockets have some limitations when it comes to security. For example, because you cannot have custom headers when using ws: connections, it is difficult to maintain sessions - so once logged in, a user will stay logged in until some other process kills off their login.

Also, you need to understand that websockets != socket.io. Socket.io is a lot more comprehensive but also more complex and by default can fall back to long-polling instead of websockets. It has both advantages and disadvantages.

Honestly, I'm still not seeing why you want to do this. When you say you want user logins for the websocket connections, where are you connecting to?

Generally you would only want this kind of thing for connections between the node-red server and a client using a web page or between 2 different web pages. Both of these are things that UIBUILDER could already do for you.

1 Like

I am building a node for a custom video camera application. These cameras send emit/receive events over a websocket connection. This video camera application + node red are only local and on a device without internet. The user login is just to login into the video camera application. I wanted to do this all in a configuration node but dunno how exactly

I'm not going to talk about the security side of things, you should be researching that before hand :wink:

But, the general idea will be this (and one I use often in my nodes, but how you design it, is up to you)
In a config Node, establish the connection, along with all the secret sauces that comes with it.

Then, in your config Node, create 2 methods and 1 collection.
(Note: I'm using hints of typescript here : Sorry @TotallyInformation :angel: )

const Listeners = {}

registerListener(NodeID: string, Callback: (data: buffer)) {
    Listeners[NodeID] = Callback
}

deRegisterListener(NodeID: string) {
    delete Listeners[NodeID]
}

node.ws.on('message', (data) => {
    for (const [id, cb] of Object.entries(Listeners)) {
        cb(data)
    }
})

In all your nodes that use this config.


node.myConfigNode = RED.nodes.getNode(self.config.configId)
node.myConfigNode.registerListener(node.id,(data) =>{
   node.send({payload:data})
})

and importantly

node.on('close',(removed,done) => {
   node.myConfigNode.deRegisterListener(node.id)
   done()
})

This is all boilerplate stuff - but should hint at the approach to take (at least one of)
Also remember to close the main socket in your config on the "close" callback, else you could end up with zombie web socket connections hogging resources


EDIT : The Web socket part.
in the ws npm package, you can submit headers along with the connection, and if you design your Config node to prompt for creds to facilitate these required headers you should get close.

Example (your config node):

module.exports = function(RED) {
    function Init(config) {
        RED.nodes.createNode(this, config);
        const node = this;
        node.ws = new WebSocket('wss://x.x.x.x/xxx', {
            headers: {
                someHeader: config.someValueKey
            }
        });
    }
}

I would have given your post a like Marcus but you spoiled it by using Typescript! :grinning:

2 Likes

Your welcome @TotallyInformation :kiss:

:wink:

1 Like