Timeout with socket io - node.js

I have an application using socket.io with Node and Express. I'm also using AWS EC2 and Nginx.
I'm getting a timeout with socket io.
The error is:
GET https://vusgroup.com/socket.io/?EIO=3&transport=polling&t=MnUHunS 504 (Gateway Time-out)
Express file:
var port = 8090;
host = 'https://18.237.109.96'
var app = express(host);
var webServer = http.createServer(app);
...
// Start Socket.io so it attaches itself to Express server
var socketServer = socketIo.listen(webServer, {"log level":1});
//listen on port
webServer.listen(port, function () {
console.log('listening on http://localhost:' + port);
});
Nginx file:
server {
listen 80 default_server;
listen [::]:80 default_server;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
proxy_pass http://18.237.109.96:8090/;
}
}
server {
server_name vusgroup.com www.vusgroup.com; # managed by Certbot
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
...
ssl stuff
...
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
proxy_pass http://18.237.109.96:8090/;
}
location /socket.io/ {
proxy_pass http://18.237.109.96:3000;
proxy_redirect off;
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;
}
}
I've tried chaning the proxypass for socket.io to http://18.237.109.96:8090; but that gave me a 400 error.

Related

Ubuntu + Nginx + NodeJS: 502 Bad Gateway

Currently I am trying to build a small nodejs API which should work on my server behind an already existing and working nginx setup.
nginx.conf:
server {
listen 80;
listen [::]:80;
server_name *.mydomain.com;
if ($host = www.mydomain.com) {
return 301 https://$host$request_uri;
}
if ($host = mydomain.com) {
return 301 https://$host$request_uri;
}
if ($host = hello.mydomain.com) {
return 301 https://$host$request_uri;
}
return 404;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name mydomain.com www.mydomain.com;
root /var/www/html;
index index.html;
ssl_certificate /etc/ssl/cert.pem;
ssl_certificate_key /etc/ssl/key.pem;
ssl_client_certificate /etc/ssl/cloudflare.crt;
ssl_verify_client on;
location / {
try_files $uri/index.html $uri.html $uri/ $uri =404;
}
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name hello.mydomain.com;
root /var/www/hello;
ssl_certificate /etc/ssl/cert.pem;
ssl_certificate_key /etc/ssl/key.pem;
ssl_client_certificate /etc/ssl/cloudflare.crt;
ssl_verify_client on;
location / {
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://127.0.0.1:3000$request_uri;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
index.js:
const express = require('express');
const app = express();
app.get("/", (request, response) => {
response.end("hello world");
});
app.listen(3000, () => console.log('listening'));
So i have mydomain.com and www.mydomain.com and they have nothing to do with nodejs and work fine.
The nodejs site lies behind hello.mydomain.com and just returns a 502: Bad Gateway error. When I am on my server (where everything lies) and just do:
curl localhost:3000
I get the right response. So the nodejs code works (I even approved it locally), but the nginx is not able to act as a proxy and "speak" with the local nodejs express.
Does anyone know why this does not work? I already searched through many tutorials, but I just cannot find the solution. :/

NodeJs App + AWS EC2 + Nginx + Websocket configuration

im running a Nodejs app on a Ec2 instance. The app runs node-rtsp-stream that outputs a websocket witch then uses with jsmpeg to display on the web browser.
NGINX config port 80 (this works fine)
server {
listen 80 default_server;
listen [::]:80 default_server;
location / {
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;
NGINX websocket config (this doesnt)
http {
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream websocket {
server ws://localhost:9999;
}
server {
listen 80;
location / {
proxy_pass http://websocket;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
app.js
Stream = require('node-rtsp-stream')
stream = new Stream({
name: 'stream',
streamUrl: 'rtsp://demo:demo#ipvmdemo.dyndns.org:554/onvif-media/media.amp',
wsPort: 9999,
ffmpegOptions: { // options ffmpeg flags
'-stats': '', // an option with no neccessary value uses a blank string
'-r': 30 // options with required values specify the value after the key
}
})
Script tag on HTML
player = new JSMpeg.Player('ws://localhost:9999', {
canvas: document.getElementById('canvas')
Should this be calling for 'ws://localhost:9999' or something else?. On Browser says that can not find 'ws://localhost:9999'
Each nginx config file is stored in sites-available
Thanks for your time!!!

How can I get visitors IP by Node.js?

I have my own VPS server and I have script in Node.js which display the visitor's IP but always when I visit website I get in console local IP address (127.0.0.1). I use Nginx.
Any idea?
Node.js script:
#!/usr/bin/env nodejs
const http = require('http');
const host = '127.0.0.1';
const port = 8080;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
var ip = (req.headers['x-forwarded-for'] || '').split(',').pop().trim() ||
req.connection.remoteAddress || req.socket.remoteAddress || req.connection.socket.remoteAddress;
console.log(`IP = ${ip}`);
});
server.listen(port, host);
Nginx proxy/headers configuration:
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name _;
location / {
try_files $uri $uri/ =404;
proxy_pass http://127.0.0.1:8080;
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 need to rig your nginx reverse proxy to pass along the requester's IP address. Adding these two settings to nginx.conf does the trick.
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
Put these lines in your location{...} stanza of nginx.conf along with your proxy-pass and the rest.
With these changes, nginx inserts two http headers into each request: X-Forwarded-For and X-Real-IP. (There's a new standard Forwarded: header, but nginx doesn't handle it easily as of mid-2020.)
Then, use app.set() to add proxy server support to your nodejs program to interpret those headers. Put this line in your www or http-server.js Javascript program shortly after your const app = express() line.
app.set( 'trust proxy', 'loopback' )
Express will then muck around with the X-Forwarded-For header for you and put the appropriate IP address in req.ip.
I've linked to some documentation. You would be wise to read it.

Nginx + nodejs, socket.io for https dosnt work

I have a problem with customizing my nodejs app on the server (https, socket.io).
I using: pm2, nginx(works on port :3000), nodejs
Prev I customized nginx for :80 port(http) - works fine!.
But when I inserted ssl certificate and customized him I get errors in the console:
"Access to XMLHttpRequest at 'https://example:2053/socket.io/?EIO=3&transport=polling&t=NAPoEIt' from origin 'https://example.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
My nginx settings:
server {
listen 80 default_server;
server_name example.com www.example.com;
return 301 http://skinsgaben.com$request_uri;
}
server {
listen 443 ssl;
server_name site.com www.example.com;
ssl_certificate /var/www/site/ssl/example.crt;
ssl_certificate_key /var/www/site/ssl/example.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
location / {
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://localhost:3000/;
proxy_redirect off;
# Socket.IO Support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location /socket.io/ {
proxy_pass http://localhost:3000/;
proxy_redirect off;
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;
}
error_log /var/www/site-log/error.log;
access_log /var/www/site-log/access.log;
}
I'm mostly using this pattern for local and remote nodejs apps.
let host = process.env.host || 'your host';
let PORT = process.env.port || 'your port';
let protocol = 'http';
let options = {};
if (APP_ENV === 'production') {
protocol = 'https';
options = {
key: fs.readFileSync(SSL.KEY),
cert: fs.readFileSync(SSL.CERT)
};
}
const server = require(protocol).createServer(options, app);
server.listen({ host, port: PORT }, () => {
console.log(`Server listening on `);
});

Port numbers not hiding in nginx reverse proxy (next js server)

I am trying to deploy a next-js app by create-next-app, I have a custom express server like this -
const express = require('express')
const next = require('next')
const dev = process.env.NODE_ENV !== 'production'
const nextApp = next({ dev })
const handle = nextApp.getRequestHandler()
const fs = require('fs')
nextApp.prepare()
.then(() => {
const server = express ()
let port = 3000;
let options = {
key: fs.readFileSync('some key..', 'utf-8'),
cert: fs.readFileSync('some cert..', 'utf-8'),
};
server.get(
...
)
let app = https.createServer(options, server)
.listen((port), function(){
console.log("Express server listening on port " + port);
});
})
.catch((ex) => {
console.error(ex.stack)
process.exit(1)
})
I want to deploy this as the website when someone types the URL subdomain.maindomain.com so I saved two nginx configuration files like this -
/etc/nginx/sites-available/default AND /etc/nginx/sites-available/subdomain.maindomain.com
the default file contains this
server {
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name maindomain.com www.maindomain.com;
location / {
# try_files $uri $uri/ =404;
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;
}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/maindomain.com/fullchain.pem;$
ssl_certificate_key /etc/letsencrypt/live/maindomain.com/privkey.pe$
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
and the subdomain.maindomain.com file looks like this
server {
if ($host = www.subdomain.maindomain.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
if ($host = subdomain.maindomain.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
root /var/www/subdomain.maindomain.com/somecodefolder/;
index index.html index.htm index.nginx-debian.html;
server_name subdomain.maindomain.com www.subdomain.maindomain.com;
location / {
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;
# try_files $uri $uri/ =404;
}
}
if I'm typing https://subdomain.maindomain.com:3000, everything works fine, I see my website running. But when I type https://subdomain.maindomain.com (without the port number) it shows nothing. How can I get the content I want when I type just the url without the port number. I have tried many combinations, but could'nt do. someone please help i've been trying since 2 days.
Try with other applications in order to validate if something is wrong in your application.
Configure nginx to use domain instead ports are not complex. Just add https configurations but the main configurations will be the same.
Steps
npm install
node main_domain.js
node subdomain.js
Check if webs are working:
Add the following lines to your /etc/hosts. This will help us to use domains without enterprise web hosting company register.
127.0.0.1 maindomain.com
127.0.0.1 subdomain.maindomain.com
Create a file in /etc/nginx/conf.d called maindomain.com.conf or whatever you want but with .conf
server {
listen 80;
server_name maindomain.com;
location / {
proxy_pass http://localhost:3000/;
}
}
Create a file in /etc/nginx/conf.d called conf.d/subdomain.maindomain.com.conf or whatever you want but with .conf
server {
listen 80;
server_name subdomain.maindomain.com;
location / {
proxy_pass http://localhost:3001/;
}
}
Restart the nginx
service nginx restart
And now, you could use a domain instead ip:port
Try to change from
proxy_pass http://localhost:3000;
Into
proxy_pass http://127.0.0.1:3000;

Resources