I am using websockets to talk with server but I want to prevent client from connecting if a requirement is not met. My code is very simple
let socket = new WebSocket('wss://server.com/server/');
socket.addEventListener('open', function(e) {
// we are now connected
});
How does nodeJS connect? It must send a connect message right? Is there a way to edit that message? I'd like to limit it so connections can not be made unless a key is sent with the connection message.
How it works now I send a "login request message" and if the credentials dont match I terminate the connection but currently people could still open connections without sending the login request. This would be a security issue right? People could just DDOS by creating a bunch of connections without logging in.
It's not NodeJS's responsibility to manage DOS/DDOS requests. That is done at the network layer (routers, switches, load balancers, proxies, etc.). See this answer for more detail: protection agains DOS websocket with ip address
Preventing users from continuing to communicate over the socket can be done after a successful connection is made and then the key sent, after which, if it's marked as valid by the server, it continues, otherwise it closes the connection. The limits on how many times a client can connect (or in this case re-connect) are handled by the network rules.
Related
When I connect to the socket server from the client side, which is considered react, every few seconds a repeated request is sent by the socket client. Generally, the requests are of get type and most of the time they are in pending mode. Sometimes the result of requests is 2.
What do you think is the problem of sending repeated requests after connecting or doing anything with the socket?
UPDATE
This problem occurs when I use namespace . I tried all the solutions but this problem was not solved.
image
This is expected behavior when the option used for transport is polling (long-polling).
What happens is, by default, the transport parameter is ["polling", "websocket"] (client, server), where the sequence of elements matters. So, the first connection attempt is made via polling (which is faster to start compared to websocket), and then (or in parallel, I don't know the working details) there is a connection attempt by websocket (this takes a little longer to establish but is faster for later communication).
If the websocket connection is successfully established, the communication will be carried in this way. But if an error occurs, or the connection takes a long time to be established, or this transport option is not present in the instance's parameters, then the communication will continue being carried out through polling, which are the various requests that remain pending. It is normal for them to remain pending, so they receive an update and are able to inform the requester immediately, without the need for several quick requests consulting the application's status.
Check the instance parameters you set for this connection to find out if transport via websocket is enabled. Be careful when using the socket server behind a reverse proxy, as this reverse proxy needs to be properly configured to accept websocket connections, otherwise it won't work.
You can check the websocket requests in the browser inspection, Network tab, by enabling the WS filter.
Here are some additional links for you to read more about:
https://socket.io/docs/v4/how-it-works/
https://socket.io/docs/v4/using-multiple-nodes/
https://socket.io/docs/v4/reverse-proxy/
https://ably.com/blog/websockets-vs-long-polling
I have a task to create a Spring-integration TCP client which should connect to a server and receive messages from it:
The server is responsible for sending "heartbeat" and data messages and doesn't expect any incoming messages from the client, except acknowledgements.
The client must open and maintain (reopen) a connection to the server.
As I understand, TcpNetClientConnectionFactory opens a connection only upon sending a message. Is there any way to open a connection without sending any data (something like SocketFactory.createSocket(host, port) does) and maintain it?
Please, investigate a TcpReceivingChannelAdapter and let us know why it doesn't work for you:
https://docs.spring.io/spring-integration/docs/current/reference/html/ip.html#tcp-adapters
Is there a limit how many clients a NodeJs server can handle with server sent event? As far as I understood, the server has to keep a connection to be able to send messages to the browser. How can I know how many connections be be held open without pen-testing, since it will be a shared hosting for now.
On the Server side for websockets there is already an ping/pong implementation where the server sends a ping and client replies with a pong to let the server node whether a client is connected or not. But there isn't something implemented in reverse to let the client know if the server is still connected to them.
There are two ways to go about this I have read:
Every client sends a message to server every x seconds and whenever
an error is thrown when sending, that means the server is down, so
reconnect.
Server sends a message to every client every x seconds, the client receives this message and updates a variable on the client, and on the client side you have a thread that constantly checks every x seconds which checks if this variable has changed, if it hasn't in a while it means it hasn't received a message from the server and you can assume the server is down so reestablish a connection.
You can achieve trying to figure out on client side whether the server is still online using either methods. The first one you'll be sending traffic to the server whereas the second one you'll be sending traffic out of the server. Both seem easy enough to implement but I'm not so sure which is the better way in terms of being the more efficient/cost effective.
Server upload speeds are higher than client upload speeds, but server CPUs are an expensive resource while client CPUs are relatively cheap. Unloading logic onto the client is a more cost-effective approach...
Having said that, servers must implement this specific logic (actually, all ping/timeout logic), otherwise they might be left with "half-open" sockets that drain resources but aren't connected to any client.
Remember that sockets (file descriptors) are a limited resource. Not only do they use memory even when no traffic is present, but they prevent new clients from connecting when the resource is maxed out.
Hence, servers must clear out dead sockets, either using timeouts or by implementing ping.
P.S.
I'm not a node.js expert, but this type of logic should be implemented using the Websocket protocol ping rather than by your application. You should probably look into the node.js server / websocket framework and check how to enable ping-ing.
You should set pings to accommodate your specific environment. i.e., if you host on Heroku, than Heroku will implement a timeout of ~55 seconds and your pings should be sent before this timeout occurs.
I have a page on which users connect to my node server with socket.io but I only allow them to have one open socket.io connection to the server (by passing along their account id when authorizing them and storing it in an array) and this works fine 99% of the time. The problem is that sometimes when users disconnect, the serverside disconnect event doesn't fire for some reason, so I can't clear their account from the array of clients, which ends up with them being locked out.
Is there a way for me to check if their old socket connection (which I have the ID of) is still active? (So if it isn't I can clear their old connection and let them connect again)
Make sure that heartbeats is set to true (the default). If the timeout lapses, disconnect should happen automatically. However, there was a bug report about heartbeats not working. Make sure you have the latest version of Socket.IO (I'm not sure the status of the bug).
If you still need help, you could send a ping to the old connection when the user tries to reconnect:
Emit a 'ping' from the server, and reply with 'pong' from the client if the connection is still alive. If the ping times out (after say, 20 seconds), drop the connection manually so the user can reconnect. You could use the ping to notify the original client that another client is trying to connect, and raise some UI to that effect.