Socket connection not recognising all clients/connections - node.js

So far sockets is working as expected. On my server I have:
const io = require('socket.io')(1923);
// after an action
io.sockets.emit('items', data);
Then on the client side:
const socket = io.connect('http://localhost:1923');
socket.on('items', (items) => {
// do stuff with items
});
Now this is working nicely when I'm on my own machine. As soon as different devices open the site it only updates on the browsers on my computer.
Computer
Firefox has the site open
Chrome too
Mobile
Site is open on Chrome for mobile
Now after an action takes place, only the sites on the computer gets updated and not my new device. Checking the connections it also only recognises clientsCount: 2. (instead of 3)
The site is open on three separate browsers. What am I doing wrong for this to be happening?
(sidenote: I've tried the same with a second computer, it's not specific to the mobile device.)

Making my comment into an answer since it seemed to have solved your issue...
This client code:
const socket = io.connect('http://localhost:1923');
won't work anywhere except on the same computer as the server is on. localhost is, by definition`, the local computer and only the local computer. You will need to connect by IP address or by DNS name.
Perhaps you want this:
const socket = io.connect('http://192.168.0.10:1923');

Related

connect by socket.io for react native and sails

I am trying to connect mobile app with react native and nodeJS running with sails
I have test the connection with reactJS and the socket work fine on the browser but with react native it give me this error
The socket was unable to connect.
The server may be offline, or the
socket may have failed authorization
based on its origin or other factors.
You may want to check the values of
`sails.config.sockets.onlyAllowOrigins`
or (more rarely) `sails.config.sockets.beforeConnect`
in your app.
More info: https://sailsjs.com/config/sockets
For help: https://sailsjs.com/support
I have tried to add onlyAllowOrigin and add on it the url for connect and I have added origin in the header for the frontend part but all didn't work
this is the setup I used in frontend
let socketIOClient = require('socket.io-client');
let sailsIOClient = require('sails.io.js');
let token = 'my jwt token'
let io = sailsIOClient(socketIOClient);
io.sails.url = 'http://localhost:1337/';
io.sails.headers = {authorization:token,origin:'http://localhost:3000'}
useEffect(() => {
io.socket.on('my event',(data) => {
console.log({data})
})
})
backend setup
var io = sails.io
io.emit('my event, {data:'my data'});
I think your issue may be that, as you said you are testing on a 'device' if that is the case then
io.sails.url = 'http://localhost:1337/';
Will not work, the device has no access to localhost, you need to make the socket server publicly available, even if you are using wifi. Localhost is just that, local to the host. Your app can access it on the desktop because, well its local but when its on the device it will try and connect to itself on port 1337, but nothing is running there so its failing.
I would suggest just pushing your code to a public server of some sort (socket server that is)
Some inexpensive / free location are
AWS (free tier)
Digital Ocean ( 100.00 credit or 5.00 / month)
Linode
(100.00 credit or 5.00 / month)
There are many others, but these are some popular ones, also with all options they have pre configured node instances that make it easy to get up and running quickly.

websocket creating new connection every second

I have an angular 5 application which uses a socket.io-client to connect to a websocket server which is hosted on google cloud platform. However instead of opening 1 connection, I see in the browser multiple connection being created, with a new connection opening every second. I added a debug breakpoint in the code where the connection is open and it is triggered only once when the page load. Not sure why it keeps on requesting for a new connection even though the initial connection was successful with 101 code.
private BASE_URL = 'wss://X.XXX.XX.XXX/';
private socket: any;
connectSocket(userId: string) {
this.socket = io(this.BASE_URL, { query: `userId=${userId}`, transports: ['websocket'] });
}
I'd need more information to answer this with certainty, but I could make an educated guess as to what's happening here.
I think the connection code might be placed in a bit of code that gets executed over and over again, causing it to show this behavior.
Additionally, if this is indeed a server problem, you can easily see what the server actually sent back, that caused the socket to close. In Chrome, click on the "name" of the request in the "Network" tab, and then click on "Frames" tab - that should show you exactly what kind of information travelled between the client and the server.

Raspberry + socket.io works on local network but not from outside

I have a Raspberry Pi serving an html page through a server.js file. The main lines (not all the code) are:
var app = require('http').createServer(handler);
var io = require('socket.io').listen(app);
...
app.listen(8000);
...
fucntion handler(req,res) {
fs.readFile(__dirname+'/../index.html' function(err,data) {
...
io.sockets.on('connection', function (socket) {
setInterval(function(){
...
socket.emit('tempUpd',date,temp);
}, 2000);
});
On the index.html:
<head>
...
<script src="/socket.io/socket.io.js"></script>
...
</head>
<body>
<div id="info"></div>
---
<script>
var socket = io.connect('http://192.168.1.6:8000');
socket.on('tempUpd', function(date, temp){
document.getElementById("info").textContent = temp;
});
...
</script>
</body>
</html>
As you can see, the idea is to update a temperature measurement every 2 seconds.
When I connect from my smartphone to my Raspberry PI through the local network (using wireless), everything works as expected and I can access the webpage and see the temperature values changing every 2 seconds.
When I turn off the wireless on the smartphone and connect to the Raspberry through the mobile network (having configured my router to allow the connection to pass to the raspberry pi), I can see the webpage, but all the information passed through the socket is never displayed.
Thinking that for some reason I wasn't able to see dynamic elements on that page, I added another , and added some code so that it showed current time every 2 seconds with setInterval. I see time changing, but nothing that comes through the socket gets displayed. Again, I switch to the local network, and everything is visible, including the info passed through the socket.
Any idea on what might be happening?
Thank you very much!!
192.168.1.6 is a local network address. You can't access that address from outside your local network. The mobile network is outside your local network. When you use WiFi from your phone, you are connecting to the access point inside your local network and you can then route to 192.168.1.6.
To access it from the public mobile network (from outside your own local network), you would have to have a public IP address that was routed to your server from outside your local network.
A common way to solve this is to get a public IP address (or use dynamic DNS for DHCP assigned addresses) for your internet connection and then configure "port forwarding" on your internet router. This will take incoming packets destined for a particular port on your public IP address and forward them to a specific device (e.g. your Raspberry Pi) on your internal network.
You need to update the index.html page to open your socket dynamically, based on the ip address of the node server. As others have pointed out, when you are connecting to the server from the internet, your Pi isn't at 192.168.1.6. (that's your local network)
If you are able to hit the web page then you have your router is forwarding things correctly.
On you index.html page, change the line from:
var socket = io.connect('http://192.168.1.6:8000');
to:
var socket = io.connect('http://' + location.host + ':8000');
Also make sure you are forwarding port 8000 on your router to your Pi as well.
Good luck.
--Ed

Websocket server running fine but cannot connect from client (what url should I use?)

OK this is very simple to anyone who's used websocket and nodejs.
I have created a websocket server named ws_server.js and put it in C:\Program Files (x86)\nodejs where I have installed the nodejs framework. I started the server and it is running and it says it's listening on port 8080. So far so good, I have the server running.
Now I simply want to connect to it from client code so that I can do all that lovely stuff about capturing events using event listeners etc. The problem is, embarassingly, I cannot figure out what URL to use to connect to my websocket server.
function init() {
testWebSocket();
}
function testWebSocket() {
websocket = new WebSocket("ws://localhost:8080/"); // WHAT URL SHOULD BE USED HERE?
websocket.onopen = function(evt) { alert("OPEN") };
websocket.onclose = function(evt) { alert("CLOSE") };
websocket.onmessage = function(evt) { alert("MESSAGE") };
websocket.onerror = function(evt) { alert("ERROR") };
}
function doSend(message) {
// this would be called by user pressing a button somewhere
websocket.send(message);
alert("SENT");
}
window.addEventListener("load", init, false);
When I use ws://localhost:8080 the only events that trigger are CLOSE and ERROR. I cannot get the client to connect. I must be missing something very simple. Do I need to set up my nodejs folder in IIS for example and then use that as the URL?
Just to reiterate, the websocket server is running fine, I just don't know what URL to use to connect to it from the client.
EDIT: The websocket server reports the following error.
Specified protocol was not requested by the client.
I think I have got it working by doing the following.
var websocket = new WebSocket("ws://localhost:8080/","echo-protocol");
The problem being that I needed to specify a protocol. At least now I get the onopen event. ...if nothing much else
I was seeing the same error, the entire web server goes down. Adding the protocol fixes it but leaves me wondering why it was implemented this way. I mean, one bad request should not bring down your server.
You definitely have to encase it a try/catch, but the example code provided here https://www.npmjs.com/package/websocket (2019-08-07) does not. This issue can be easily avoided.
I just wanted to share a crazy issue that I had. I was able to connect to a websocket of an old version of a 3rd party app in one computer, but not to a newer version of the app in another.
Moreever, even in new computer with the new version of the app, The app was able to connect to the websocket, but no matter what I did, when I tried to connect with my own code, I kept getting the error message that the websocket connection failed
Long story short, They changed an apache configuration that allowed connecting to the websocket via a proxy.
In the old version, apache config was:
ProxyPass /socket/ ws://localhost:33015/ retry=10
ProxyPass /socket ws://localhost:33015/ retry=10
In the new version, apache config was changed to:
ProxyPass /socket/ ws://localhost:33015/ retry=10
By bad luck, I was trying to connect to ws://localhost/socket and not to ws://localhost/socket/. As a result, proxy was not found, and connection returned an error.
Moral of the story: Make sure that you are trying to connect to a websocket url that exists.
For me, the solution was to change the URL from ws:// to wss://. This is because the server I was connecting to had updated its security, and now only accepted wss.

Had to increase http.globalAgent.maxSockets for iOS simulator, but why?

I have a proxy server built in nodejs. It was working fine, until I tried browsing the web through it via the iOS iPhone simulator. Then it would load a few requests and hang indefinitely.
I narrowed it down to this:
var req = http.request({...}, function(){
// this is not being called for some requests
})
...which in turn let me to discover this:
req.on('socket', function(){
// this is not being called for some requests
})
Suspecting trouble with pooling of sockets, I set http.globalAgent.maxSockets = 50 and that indeed fixed it. (The default is 5.) But I feel like I've only fixed the symptom of a deeper problem. It only happened when I browsed from within the iOS simulator, via xcode. Using desktop Chrome, not in the simulator but using that same proxy instance, there were no problems.

Resources