How to prevent flooding of messages to socket.io server? - javascript

I wrote chat application using NodeJs and Socket.io. It works fine but at the moment there is nothing stopping malicious user from flooding server with large number of messages. What would be the best way to avoid this kind of situation?
BTW I did quite a bit of research and currently it seems that the only option would be simply tracking frequency of messages that user sends to server and if its over certain threshold disconnect socket or simply ignore messages. Is there a better way?

Related

Socket.io clients seem to connect to different sockets on the same server

Hi I'm running a standard (example) socket.io chatroom, but I'm running into a problem I'm not sure how to debug.
The chatroom seems to functioning normally, clients can broadcast their messages, but occasionally on connection it is as if they are alone in the chatroom when they are not -- other clients don't see their presence or messages. It frequently happens when clients are not joining the socket around the same time.
It is as if they've connected to an entirely different socket.
I think it might be something to do with cookies and sessions. If the clients clear their sessions they are reunited in the chat.
Perhaps on (or before) connection I could clear session data? How?
There is no requirement for a chat server that clients connect on the same IP and port. Typically, there is a requirement that they connect to the same server, which must maintain a list of client connections to enable chat between them.
Chat works like this:
Server sets up a ServerSocket to accept connections. Clients connect, and these connections are stored on the Server in an array, object or some other form. When the server gets a message event from one of the clients, this message is then broadcast to all the other clients.
Thus, if you have one client who is not receiving any messages and appears to be in an empty room, the issue is likely that they are somehow not part of the same collection of connected clients, part of the same chat app, or not connected at all.
Okay I think I figured it out, I was right and wrong.
I think the clients were connecting to 'entirely different sockets' but it had nothing much to do with cookies and sessions:
I discovered (due to some other really weird bugs) by a study of running processes that somehow an old version of the socket.io server script was clinging to life in the background for some time. I expect clients were connecting to one of the two io server scripts randomly: not good. Working in a sense, but in separate worlds.
Killing those rogue processes seems to have fixed a lot of stuff.

Socket.io - remove jitter?

I have not been able to get an answer to this anywhere online. I want to remove possible jitter from my nodejs server. I am using socket.io to create connections to node.
If a user goes to a specific part of my website, a connection is started. However, if the user refreshes the site too quickly and often, the connection is created very frequently, and issues arise with my server.
While I realized it's possible this could be solved a couple different ways, I am hoping a server solution is out there. Meaning, whenever a user connects, make sure the user is connected for at least 5 seconds. Then move on. Otherwise, disconnect the user. Thanks for any insight!
First off a little background. With a default configuration, when a socket.io connection starts, it first does 2-5 http connections and then once it has established the "logical" connection, it tries to establish a connection using the webSocket transport. If that is successful, then it keeps that webSocket connection as a long lasting connection and sends socket.io packets over it.
If the client refreshes in the middle of the transition to a webSocket connection, it creates a period of unknown state on the server where the server isn't sure if the user is just still in the middle of the transition to a lasting webSocket connection, if the user is gone entirely already, if the user is having some sort of connection issues or if the user is doing some refresh thing. You can easily end up with a situation where the server thinks there are multiple connections all from the same user in the process of being confirmed. It can be a bit messy if your server is sensitive to that kind of thing.
The quickest thing you can do is to force the connection process to go immediately to the webSocket transport. You can do that in the client by adding an options to your connection code:
let socket = io(yourURL, {transports: ["websocket"]});
You can also configure the server to only accept webSocket connections if you're try to protect against any other types of connections besides just from your own web pages.
This will then go through the usual webSocket connection which starts with a single http request that is then "upgraded" to the webSocket protocol. Once connection, one socket. The server will know right away, either the user is or isn't connected. And, once they've switched over to the webSocket protocol, the server will known immediately if the user hits refresh because the browser will close the webSocket immediately.
The "start with http first" feature in socket.io is largely present because in the early days of webSockets, there were some browsers that didn't yet support them and some network infrastructure (like corporate proxies) that didn't always support webSocket connections. The browser issue is completely gone now. All browsers in use support webSocket connections. I don't personally have any data on the corporate proxies issues, but I don't ever hear about any issues with people using webSockets these days so I don't think that's much of an issue any more either.
So, the above change will get you a quick, confirmed connection and get rid of the confusion around whether a user is or isn't connected early in the connection process.
Now, if you still have users who are messing things up by rapid refresh, you probably need to just implement some protection on your server for that. If you cookie each user that arrives on your server, you could create some middleware that would keep track of how many page requests in some recent time interval have come from the browser with this cookie and just return them an error page that explains they can't make requests that quickly. I would probably implement this at the web page level, not the webSocket level as that will give users better feedback to stop hitting refresh. If it's really a refresh you're trying to protect against and not general navigation on your site, then you can keep a record of a combination cookie and URL and if you see even two of those within a few seconds, then return the error page instead of the expected content. If you redirect to an error page, it forces a more conscious action to go back to the right page again before they can get to the content.

Handling oversized messages with socket.io

I have a nodejs project that spawns multiple processes that communicate with socket io (the process both send data and receieve it).
Sometimes during feature development, other programmers might do mistakes that will cause my socket infrastructure code to send large messages that are over size X (for example, over 500MB).
I am looking for a way to catch such cases and log them, I also wan't that such specific request specifically will fail.
Right now the behavior is that the entire socket connections fails (not just the specific big messages) and I didn't find anyway to even catch the case in order to know that this is the cause.
Right now I limit the message size with the "maxHttpBufferSize" configuration:
Socket.IO doc about it here - "how many bytes or characters a message can be, before closing the session (to avoid DoS)."
But I can't seem to catch any error when this size exceeds and the entire connection fails which is very bad for me.
I did think about trying to add some checks around my sending data through socket code, to check myself if the message size is to big, but serializing the data to make this check will have a very heavy price on performance, and socket.io code should already be doing this before sending the data so I don't want to make this happen twice.
The best solution i'm hoping to find is a socket.io supported way to handle this, if there is a different way that is performace costy that can also be good.
Note: I am working with socket io 2.0.4.
If there is a fix only in higher version that's also acceptable.

Socket.io inconsistent send times

Ive been experiencing some freezes in my web application. So I decided to measure the time between the packets that arrive on the client. The are sent from the server at a consistent rate: every 100ms
However on the client sometimes there is a 700ms difference between packets. I did some testing on the server side and the packets are sent consistently between 100-110ms
When this freeze happens, the client doesnt receive any packets for around 700ms and then receives 7 packets all at once.
Is this a connection issue or an issue with socket.io itself? I am using socket.io 2.0.3
The socket isnt sending too much data. This even happens when it is just serving a single client
My first problem with socket.io was building simple chat app, when i send too many messagens it freezes around 500ms, and sometimes send 2 equal messages when it was freezed, i end up figuring out it was a problem with my database connection and the way i was rendering the messages on the client. So it may be yours (or may be not).
And also it would be nice if you share you code so expert users can help you.
I recommend you to create another application with a simple/likely you socket request, if it run correctly you should check your code.

setInterval($.get or socket.io? [duplicate]

I am developing a web app and I was wondering which method should be suitable for my project.
Basically what I want to display to the users are some notifications which are taken from requests to other servers. My node.js app gets all the info and then it spread out to the users, saving a copy into my MongoDB.
The idea is quite simple but reading about methods I found these two techniques:
Ajax : Client side would be checking all time if there is new content on the server. This would be done by using a jquery ajax get to my server API (every 30/60 seconds).
Socket.io : The client connects once, and then a permanent TCP connection is maintained (more realtime).
Now I have explained the situation, I have the following questions :
Would I not have too many requests with ajax ? imagine I want a check every minute to the server, if we scale the app to 100 users, it will give me 100 queries per minute. Would it be "cheaper" in system resources to have a socket ?
Would the socket.io be a problem for mobile devices ? bandwith and performance. The response of the server is always info in JSON format.
I read that now.js could be used for this but it seems the project is no longer supported, so not sure if using it would be a good idea.
How is the caching on both methods ? I was considering to create a cache file for each user and this would be updated by the node.js in the server side. I guess this could work really well with ajax but what about socket.io ?
Is it true that socket.io is not compatible at all with many browsers ? My app would be more focused to mobile devices and I think this could make me think about choosing ajax instead.
Any alternative suggested ?
I hope this could clear my mind and others who are in the same situation :)
Thanks
Many of the generic tradeoffs between webSocket and Ajax are discussed here:
websocket vs rest API for real time data?
Some tradeoff issues for mobile devices are discussed here:
Cordova: Sockets, PushNotifications, or repeatedly polling server?
In a nutshell, if your data is primarily server-driven and then needs to be sent out to clients and you desire fairly good latency for when the clients see the new data, then that is the exact problem that webSockets are good for. webSockets work best in this situation because the client does not need to poll frequently, the server does not need to handle regular polling requests from lots of clients. Instead, each client just sets up the one persistent webSocket communication channel which the server can then send data down upon demand at any time.
Would I not have too many requests with ajax ? imagine I want a check
every minute to the server, if we scale the app to 100 users, it will
give me 100 queries per minute. Would it be "cheaper" in system
resources to have a socket ?
Sockets require very little resources when they are not active so yes, a peristent webSocket is more efficient than lots of clients polling endlessly. This is why webSockets were invented because they are better at solving this particular problem.
Would the socket.io be a problem for mobile devices ? bandwith and
performance. The response of the server is always info in JSON format.
socket.io is not a problem for bandwidth or performance. There are some mobile issues with trying to use webSockets in the background because mobile devices are also trying to do active power management, though a similar issue exists with client polling too.
How is the caching on both methods ? I was considering to create a
cache file for each user and this would be updated by the node.js in
the server side. I guess this could work really well with ajax but
what about socket.io ?
It is unclear what you are asking about caching? In a webSocket implementation, the server gets the data and then just sends it to each user. No server-side caching would generally be needed. In a client Ajax polling implementation, the server would have to store the data somewhere and "wait" for each client to then request the data. There is no "built-in" caching mechanism for either webSocket or Ajax.
Is it true that socket.io is not compatible at all with many browsers
? My app would be more focused to mobile devices and I think this
could make me think about choosing ajax instead.
socket.io is fully compatible with all browsers that have webSockets which is pretty much everything in use today except for IE9 and older. If you use the socket.io library, it will automatically fall back to long polling if webSockets don't exist. Your mobile issues are likely going to be similar whether you're doing regular polling or webSocket because the mobile device wants to power manage long running things, but you don't want to stop polling. I don't think this is a reason to avoid webSockets/socket.io. socket.io has some really nice auto-reconnect logic whenever it loses the connection which can be really useful.
In the mobile world, I think you're just going to find that you can't reliably do real-time notifications in the background without using some sort of native app component that can plug into the native "push" system on the device because that's the only system that is both battery efficient and fully compatible with power management. A web page is going to be power managed as soon as it is not the foreground task or when the device has been idle.

Categories

Resources