Socket.io not working with nginx and https - node.js

I have a React app communicating with a very simple node backend, it works perfectly fine in local and was working perfectly fine over http. For obvious reason, the app is now running in https but the socket is not connecting anymore. I have been looking to so many threads but couldn't find a way to fix it. Here are the socket parts of my code and nginx conf.
Client side:
const socket = io('wss://sub.domain.io', { path: '/my-path',});
Server side:
const server = require('http').createServer();
const io = require('socket.io')(server, {
path: '/my-path',
serveClient: false
});
server.listen(8080);
nginx proxy
server {
....website serving part...
location /my-path/ {
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
Error is: GET https://sub.domain.io/my-path/?EIO=3&transport=polling&t=MsCot3e net::ERR_CONNECTION_TIMED_OUT VM17:1 which looks like a timeout because it fails to connect.

So I found an answer after so many hours and it is pretty dumb and simple. My Nginx only handle the www website (DNS redirection is enough for the website), hence I needed www.sub.domain.io here:
const socket = io('wss://www.sub.domain.io', { path: '/my-path',});

Related

404 - Trying to acess socket.io over nginx

I am very lost at the moment, so much so that I actually signed up because of my problem. So here we go: I am running a System with Plex and I am trying to get a node.js Backend with socket.io to work that is running behind Nginx.
The proxy pass for my HTML (I am using ejs to be precise, not sure if relevant) hosted via express works like a charm. But I get a 404 error when my website tries to connect to my backend via socket.io.
My Nginx directives as configured via Plex:
location = / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://127.0.0.1:50090;
}
location /socket.io/ {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:50090/socket.io/;
}
My client connecting to the backend:
var socket = io.connect('https://subdomain.mydomain.com', {secure: true});
My Backend listening:
const app = express();
const http = require('http').createServer(app);
const io = require('socket.io').listen(http);
http.listen(50090, "127.0.0.1");
There is a lot about this on the internet, but it seems like I tried everything by now and nothing worked. Likely because I am very new to this.

Multiple sailsjs applications running on same port

I need to run multiple sails web application on the port and run a small server to route between them by application name.
Using next code, I could route between them by adding application name after the port 3000.
var express = require('express');
var app = express();
var httpProxy = require('http-proxy');
var proxy = httpProxy.createProxyServer();
var app1 = 'http://localhost:1337/',
app2 = 'http://localhost:1338/'
app.all("/app1/*", function(req, res) {
proxy.web(req, res, {target: app1});
});
app.all("/app2/*", function(req, res) {
proxy.web(req, res, {target: app2});
});
app.listen(3000);
This Program make the redirection well but now the problem is that, how i can change the generated links in sailsjs for any file as javascript and css files?
Many thanks
Install nginx
Run your apps on different ports.
On Linux /etc/nginx/sites-available/default (different on Windows, but probably easy to find):
--
server {
listen 80;
server_name apps.dev/1;
location / {
proxy_pass http://localhost:3001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
server {
listen 80;
server_name apps.dev/2;
location / {
proxy_pass http://localhost:3002;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
You can access your apps using: apps.dev/1 or apps.dev/2
For production you can apply any domain addressed to the server.
For local dev just set virtual host to redirect anything from production domain to local nginx.

Socket.io events not received (nginx reverse proxy, server to client)

I have a nodejs socket.io app running under nginx reverse proxy.
My nginx configuration is as follows:
location ~ ^/(online|socket\.io) {
proxy_pass http://localhost:8888;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
This seems to work, and my nodejs app picks up the connection fine. On the server side socket.io I have the following:
io.of('/online').on('connection', function(socket){
This seems to work fine, and the 'connection' event is firing
The problem arises when I try to emit an event from the server to the client:
socket.join("users");
io.sockets.in("users").emit("got_users",users);
The 'got_users' event is not being picked up by the client. On the client side I have the following:
a4e.socket=io.connect('http://www.example.com/online');
This seems to work fine, but then:
a4e.socket.on("got_users",function(online_users){
This doesn't pick up the "got_users" event, no matter what I try.
Any help greatly appreciated.
I finally figured this out, the following line:
io.sockets.in("users").emit("got_users",users);
Should be replaced with:
io.of("/online").in("users").emit("got_users",users);
Then it works.

Laravel Socket.io Cross-Origin denied

I'm trying to deploy my laravel app with socket.io and I have everything up and running. Node, redis, etc. but when socket event is fired I get this exact error message.
XMLHttpRequest cannot load http://localhost/socket.io/?EIO=3&transport=polling&t=Lbe2fnV. Cross-origin redirection denied by Cross-Origin Resource Sharing policy.
I have gone into my nginx config file and added the following:
upstream app_yourdomain {
server 127.0.0.1:3000;
keepalive 8;
}
location ~* \.io {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
but it doesn't do anything.
How can I get rid of the cross-orgin error?
My biggest success came from this post
NodeJS server on DigitalOcean using socket.io returns connection refused
Try to set the origins property like so.
io.set('origins', 'http://localhost:3000');
You can put in every url you allow to get the request from for example
io.set('origins', 'http://google.com:80');
or allow all
io.set('origins', '*:*');
More about the origin property can be found here

Mixed content error when proxying websocket through nginx with SSL

I am working on a node.js application using express to serve content and socket.io for websocket communication. The setup has been working fine, but now I want to be able to access the websocket via SSL, too. I thought using nginx (which we already used for other stuff) as a proxy was a good idea, and configured it like this:
upstream nodejs {
server 127.0.0.1:8080;
}
server {
listen 443 ssl;
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
server_name _;
location / {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://nodejs;
proxy_redirect off;
}
}
The node.js server is set up like this:
var express = require('express'),
app = express();
// some app configuration that I don't think matters
server = http.createServer(app).listen(8080);
var io = require('socket.io').listen(server);
io.configure(function() {
io.set('match original protocol', true);
io.set('log level', 0);
io.set('store', redisStore); // creation of redisStore not shown
}
Both nginx and node.js run inside a Vagrant box which forwards port 443 (which nginx listens on) to port 4443 on the host system.
With this setup, navigating to http://localhost:4443 (using Firefox 23) gives me access to the files served by Express, but when socket.io tries to connect to the socket, it throws the following error:
Blocked loading mixed active content "http://localhost:4443/socket.io/1/?t=1376058430540"
This outcome is sadly obvious, as it tries to load the JS file via HTTP from inside an HTTPS page, which Firefox does not allow. The question is why it does so in the first place.
Socket.io tries to determine which protocol is used to access the web page, and uses the same protocol in the construction of the above URL. In this case, it thinks it is being accessed over HTTP, which may be the result of being proxied. However, as I understand, setting match original protocol to true in the socket.io config is supposed to help in situations like this, but it does not in my case.
I have found numerous questions and answers here about websocket proxying, but none that deal with this particular issue. So I'm pretty much at wit's end, and would really appreciate some advice.
Change match original protocol to match origin protocol:
io.configure(function() {
//io.set('match original protocol', true);
io.set('match origin protocol', true);
...
}

Resources