Socket io cluster on same port - node.js

I need to cluster socket.IO server and want to use same port for all connections
In order to do it I create express server, configure it and then tell socket.IO to listen to this server
if(cluster.isMaster){
var cpuCount = require('os').cpus().length;
for (let i = 0; i < cpuCount; i += 1) {
cluster.fork();
} else {
const credentials = {key: privateKey, cert: certificate};
const app = express();
const httpsServer = https.createServer(credentials, app);
httpsServer.listen(8003);
const io = SocketIO.listen(httpsServer);
}
But this doesn't work for multiple servers. When I'm trying to connect to socket server I get following message:
websocket.js?13d9:112 WebSocket connection to 'wss://...' failed: Error during WebSocket handshake: Unexpected response code: 400
But in server side event listener on("connection", () => {}) works.
I have same code for creating server clusters when I render app and it works just fine.
Socket server works when there's only one socket.IO server listening to this port.
If there's a way to create multiple socket.IO listeners for one port in cluster?

Finally found the answer
Socket.io is doing multiple requests to perform handshake and establish connection with a client. With a cluster those requests may arrive to different workers, which will break handshake protocol.
So I decided to use sticky session lib for socket.IO and it works exactly as I wanted

Related

use proxy pass xampp for socket.io node js server

I been trying to open the website from my mobile. I made two servers. One using xampp and php to run the website and get data from database. The second server is for running web socket. Real time chat and drawing. So server1 is in port 3000 and server2 is in 8000. how can I open both server in my mobile?
I tried
I put this in httpd.conf:
ProxyPass /node http://localhost:8000
and then in the client side, I put:
var socket = io('http://localhost/node', { transports : ['websocket']});
I am getting error:
WebSocket connection to 'ws://localhost/socket.io/?EIO=4&transport=websocket' failed:
node js setup:
const http = require('http');
const socket = require('socket.io');
const port = process.env.PORT || "8000";
const server = http.createServer((req,res)=>{
res.end('I am connected!');
});
const io = socket(server);
io.on('connection',(socket,req)=>{
socket.emit('Welcome','Welcome to the websocket server!!');
});
server.listen(port);
xampp setup:
$login = new Login();
$user_data = $login->check_login($_SESSION['Trial_User_Id']);
[xampp window][1]

Node secure Websocket with IIS (Windows)

So I have created an application that uses a websocket in node.
In my server.js I use:
import http from "http";
import WebSocket from "websocket";
[...]
var httpServer = http.createServer(this.handleRequest);
httpServer.listen(port, function () {
console.log("Listening on port " + port);
});
var server = new WebSocket.server({httpServer: http_server});
[...]
This works, and creates a socket server on the same url.
Now, I'm trying to get this on a Windows server with IIS.
I start the application with "node server.js" and it is running on port 5003.
In IIS I use a rewrite rule to forward all incomming requests to the node server. Works perfect.
Now the problem. When I install an certificate with LetsEncrypt (Win-AMCE) the website is secure, but it won't connect to the websocket as the websocket is not secure.
According to some finds on the internet I need to use npm https
import http from "https";
import WebSocket from "websocket";
import fs from "fs";
[...]
const options = {
key: fs.readFileSync("my-site-key.pem"),
cert: fs.readFileSync("chain.pem")
};
var httpsServer = https.createServer(options,this.handleRequest);
httpsServer.listen(port, function () {
console.log("Listening on port " + port);
});
var server = new WebSocket.server({httpsServer: http_server});
[...]
The problem is, how do I get some valid certificate files. I cannot sign them self because another error will popup I guess. I cannot find the files Letsencrypt created.
So.... how do I create a secure websocket??

WebSocket is closed before the connection is established. Socket.io and React

I want to make an Chat application with Socket.io and I've followed this tutorial: https://youtu.be/ZwFA3YMfkoc. I am using React and Node.js
Everything works fine while using it locally and even on different devices on my Network. However if I am hosting my Backend on Heroku it doesn't work.
The error Message is:
WebSocket connection to 'URL' failed: WebSocket is closed before the connection is established.
(URL is the URL of my Backend with the Port). I am using SSL.
I've already tried to enable session affinity but it already was enabled.
My backend code is: (atleast the code that I think is important to the Problem)
const app = express();
const server = http.createServer(app);
const io = socketio(server);
app.use(cors());
server.listen(PORT, () => console.log("Server started on " + PORT));
My frontend code is written in React and is:
var connectionOptions = {
"force new connection": true,
reconnectionAttempts: "Infinity",
timeout: 10000,
transports: ["websocket"],
};
const ENDPOINT = "URL";
socket = io(ENDPOINT, connectionOptions);
So I've fixed my Problem.
The URL on the client side had to be without the Port.
So for example:
const ENDPOINT = "https://web.site.com";
and not:
const ENDPOINT = "https://web.site.com:1337";
Call socket.connect() or just add autoconnect: true in options you are providing.

Socket io + Node Error: getaddrinfo EADDRINFO after a few hours with < 100 connections

I have a node + socket server running to simply emit to the clients. The client is on an https domain name. After a couple or few hours my socket server starts to log { [Error: getaddrinfo EADDRINFO] code: 'EADDRINFO', errno: 'EADDRINFO', syscall: 'getaddrinfo', fatal: true } killing all of the websocket connections and not being corrected until I restart the script that is running the server. After I restard the server script everything is fine for 2-3 hours.
The load is low, only me opening 10 - 30 tabs in my web browser.
I have searched all over including these and other questions 25684451,12565209, and 29536649.
As I mentioned my domain is https://redacted.com and as a result need, I believe, the socket server needs to be https as well, which is how I built it.
Is it hardware? Ubuntu's open file limit? https issue? dns routing issue? socket connection limit? How do I even test?
Ubuntu 14.04, nodeJS v0.10.25, Socket.io 1.3.6. at AWS t2.micro for testing.
Server:
var https = require('https'),
fs = require('fs'),
mysql = require('mysql');
var options = {
key: fs.readFileSync('/etc/ssl/certs/key2/redacted.key'),
cert: fs.readFileSync('/etc/ssl/certs/key2/STAR_redacted_com.crt'),
ca: fs.readFileSync('/etc/ssl/certs/key2/redacted.ca-bundle')
};
var app = https.createServer(options);
var client = require('socket.io').listen(app); //socket.io server listens to https connections
app.listen(8080);
var connected = 1;
client.on('connection', function(socket){
function sendStatus(s){
socket.emit('status', s);
}
sendStatus('Connected');
console.log(connected);
connected++;
});
Client:
try{
var socket = new io.connect('ws.redacted.com:8080');
//var socket = io.connect('ws.redacted.com:8080');
console.log(socket);
}catch(e){
//set status to warn user
console.log('3');
console.log(e);
}

Setting socket.io client 'resource' for nginx reverse proxying path (no websockets)

I have a socket.io server only using the 'xhr-polling' transport running at port 5000 on a system with nginx configured to pass requests that start with '/api' to that port.
In my client, on connect, I specify the socket.io resource as 'api/socket.io' which appears to correctly forward the initial connection request to the server and trigger a connection event. However, responses sent from the server using socket.emit do not reach the client.
If I connect the client directly to port 5000, leave off the 'resource' option, and bypass nginx forwarding, everything seems to work ok.
Server:
var io = require('socket.io').listen(5000, {transports: ['xhr-polling']});
io.sockets.on('connection', function (socket) {
console.log('Connection spotted!');
socket.emit('connected', 'hi');
});
Client (not working):
var socket = io.connect(window.location.hostname, {resource:'api/socket.io'});
socket.on('connected', function(data) {
alert('Connected!!!');
});
Client (working):
var socket = io.connect(window.location.hostname, {port: 5000});
socket.on('connected', function(data) {
alert('Connected!!!');
});
nginx:
location / {
proxy_pass http://localhost:5000/;
}
In both cases I see the "Connection spotted!" log message on the server, but client gets data and alerts when connected directly to the port.

Resources