Heroku back logs are showing the same amount of user connected even with two different devices.
However, localhost is working fine. Each time a device connects, a new socket is generated. This is not the case on Heroku.
So its connecting fine, but that connection is the same across two different devices?
I had the server clustered. Removing that fixed the issue.
Looks like Socket.io requires additional configuration if you're going to cluster node.
Related
Hi I've been trying to figure this out for some time now. It's kind of hard to explain... Ill try and give some background : I'm trying to create a pwa that can work on WAN and LAN for when offline. ---- So I have a client and server, if I host the client and server both locally I'm having no issues I can connect to one another directly and everything, the socket.io and web socket work great. If I host the client and server both on Heroku they work great as well. The problem comes when I host the client on Heroku and the server locally -- which in the application I'm working on I need this. Im able to still connect to the other user if im using the WAN connection portion but if I try to make the connection using LAN it throws errors. I'm not sure what is going on, I'm still fairly new socketio, websockets, etc... ---- Here is the error I am getting Error Image. Here are my imports on the server - imports-server, how I'm setting up the server - server setup, how I set up the connection on the client -- client setup. Sorry if I wasn't clear on my explanation, thank you for help.
I am working on a nodejs app with Socket.io and I did a test in a single process using PM 2 and it was no errors. Then I move to our production environment(We use Google Cloud Compute Instance).
I run 3 app processes and a iOS client connects to the server.
By the way the iOS client doesn't keep the socket connection. It doesn't send disconnect to the server. But it's disconnected and reconnect to the server. It happens continuously.
I am not sure why the server disconnects the client.
If you have any hint or answer for this, I would appreciate you.
That's probably because requests end up on a different machine rather than the one they originated from.
Straight from Socket.io Docs: Using Multiple Nodes:
If you plan to distribute the load of connections among different processes or machines, you have to make sure that requests associated with a particular session id connect to the process that originated them.
What you need to do:
Enable session affinity, a.k.a sticky sessions.
If you want to work with rooms/namespaces you also need to use a centralised memory store to keep track of namespace information, such as the Redis/Redis Adapter.
But I'd advise you to read the documentation piece I posted, things might have changed a bit since the last time I've implemented something like this.
By default, the socket.io client "tests" out the connection to its server with a couple http requests. If you have multiple server requests and those initial http requests don't go to the exact same server each time, then the socket.io connect will never get established properly and will not switch over to webSocket and it will keep attempting to use http polling.
There are two ways to fix this.
You can configure your clients to just assume the webSocket protocol will work. This will initiate the connection with one and only one http connection which will then be immediately upgraded to the webSocket protocol (with socket.io running on top of that). In socket.io, this is a transport option specified with the initial connection.
You can configure your server infrastructure to be sticky so that a request from a given client always goes back to the exact same server. There are lots of ways to do this depending upon your server architecture and how the load balancing is done between your servers.
If your servers are keeping any client state local to the server (and not in a shared database that all servers access), then you will need even a dropped connection and reconnect to go back to the same server and you will need sticky connections as your only solution. You can read more about sticky sessions on the socket.io website here.
Thanks for your replies.
I finally figured out the issue. The issue was caused by TTL of backend service in Google Cloud Load Balancer. The default TTL was 30 seconds and it made each socket connection tried to disconnect and reconnect.
So I updated the value to 3600s and then I could keep the connection.
We have a server which do implement socket.io in NodeJS on Heroku.
We have a bunch of clients (Raspberry pi's) destributed on different networks across our country. They do implement socket.io clients in a NodeJS application.
It do work very well on 17/18 devices. We do have one device which are not able to upgrade the socket.io connection from a long-polling type to an actual websocket.
I cannot find the reason why.
Our server is setup with the following options:
Server settings
This is what the logs on our heroku server tells about the connection with the problematic client:
Heroku logs
As all clients are setup exactly the same way, i do not actually suspect any problems on the raspberries themselves.
Could it be a network problem where this one client is located?
- Behind the router, blocking some port etc?
Hope you have some suggestions to what the problem could be.
You tell if you need anymore information.
I was working fine with cloudamqp until all of a sudden wascally/rabbot stopped being able to connect to my endpoint. I have installed RabbitMQ locally and my system works fine. I have since then tried to setup a RabbitMq instance on Heroku via bigwig, to no avail. The endpoints I'm using should be fine and I also installed amqp.node and node-amqp to test if maybe it was a problem with rabbot. However none of these can connect either.
Any idea what the problem can be?
the most common cause is connection timeout. with all my wascally code, hosting on cloudamqp (with heroku, digital ocean or otherwise), i have to set a connection timeout much higher than the default for it to work.
this can be done with the connection_timeout parameter on the connection string url (https://www.rabbitmq.com/uri-query-parameters.html)
for example:
var conn = "amqp://myuser:mypassword#server.cloudamqp.com/my-vhost?connection_timeout=30"
this will set a connection timeout of 30 seconds
I have a big problem with socket.io connection limit. If the number of connections is more than 400-450 connected clients (by browsers) users are getting disconnected. I increased soft and hard limits for tcp but it didn't help me.
The problem is only for browsers. When I tried to connect by socket-io-client module from other node.js server I reached 5000 connected clients.
Its very big problem for me and totally blocked me. Please help.
Update
I have tried with standard Websocket library (ws module with node.js) and problem was similar. I can reach only 456 connected clients.
Update 2
I devided connected clients between a few instances of server. Every group of clients were connecting by other port. Unfortunately this change didn't help me. Sum of connected users was the same like before.
Solved (2018)
There were not enough open ports for a Linux user which run the pm2 manager ("pm2" or "pm" username).
You may be hitting a limit in your operating system. There are security limits in the number of concurrent files open, take a look at this thread.
https://github.com/socketio/socket.io/issues/1393
Update:
I wanted to expand this answer because I was answering from mobile before. Each new connection that gets established is going to open a new file descriptor under your node process. Of course, each connection is going to use some portion of RAM. You would most likely run into the FD limit first before running out of RAM (but that depends on your server).
Check your FD limits: https://rtcamp.com/tutorials/linux/increase-open-files-limit/
And lastly, I suspect your single client concurrency was not using the correct flags to force new connections. If you want to test concurrent connections from one client, you need to set a flag on the webserver:
var socket = io.connect('http://localhost:3000', {'force new connection': true});