Unable to establish websocket connection - React js + Node Express + Nginx - node.js

Please help,
Getting following error in production
WebSocket connection to 'wss://subdomain.example.com/socket.io/?EIO=3&transport=websocket' failed: Error during WebSocket handshake: Unexpected response code: 404
Here is my Configuration and code for Nginx - React Js & Node Express
Nginx Config
http {
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream node-js-myapp {
server 127.0.0.1:5000;
}
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
server {
root /var/www/html;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
server_name subdomain.example.com;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
# try_files $uri $uri/ =404;
try_files $uri $uri/ /index.html;
}
# Media: images, icons, video, audio, HTC
location ~* \.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ {
expires 1M;
access_log off;
add_header Cache-Control "public";
}
# Javascript and CSS files
location ~* \.(?:css|js)$ {
try_files $uri =404;
expires 1y;
access_log off;
add_header Cache-Control "public";
}
# Any route containing a file extension (e.g. /devicesfile.js)
location ~ ^.+\..+$ {
try_files $uri =404;
}
location /app2/ {
proxy_pass http://localhost:5000/;
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;
}
location ^~ /socket.io/ {
try_files $uri #node-js-myapp;
}
location #node-js-myapp {
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_pass http://node-js-myapp;
}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/subdomain.example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/subdomain.example.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
}
React Js
import socketIOClient from 'socket.io-client';
const socket = socketIOClient(
'wss://subdomain.example.com',
{ transports: ['websocket'] }
);
socket.on('socketToMe', function (data) {
console.log(data);
socket.emit('ABC', "abcdef");
});
Node Express
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var app = express();
var server = require('http').Server(app);
var io = require('socket.io')(server);
io.on('connection', function(socket) {
console.log("Con");
socket.on("ABC", (data) => {
console.log(data);
io.sockets.emit('socketToMe', "test test");
})
socket.on('disconnect', () => {
console.log('user disconnected')
})
})

Socket.io is not meant for connecting to a Websocket client. Read more here. You will need to use Websocket client, together with Socket.io client to broadcast data.
Socket.IO is NOT a WebSocket implementation. Although Socket.IO indeed uses WebSocket as a transport when possible, it adds some metadata to each packet: the packet type, the namespace and the packet id when a message acknowledgement is needed. That is why a WebSocket client will not be able to successfully connect to a Socket.IO server, and a Socket.IO client will not be able to connect to a WebSocket server either.

Related

Passing All Directories To Express Using Nginx

I'm trying to pass through all the directories in my app through to express, and in some cases directories that contain a dynamic 'key' which I'll :capture.
I can't get even a defined sub-directory, /pretest, to pass through to express. Despite copying the the same options for Location /, it serves me an Ngxin 404
Ideally, I want domain.com/prepop/{lookup_key} to pass to localhost:8080/prepop/{lookup_key}
Where {lookup_key} is a different value each time
Any ideas what I'm doing wrong here? Any/all help is much appreciated.
Code-
server.js
const path = require('path');
const express = require("express");
const mysql = require('mysql2');
const cors = require("cors")
const port = process.env.PORT || 8080;
const app = express();
app.use(cors())
app.get('/', (req, res) => {
res.send('hello');
});
app.get('/pretest', (req, res) => {
res.send('test');
});
app.get('/prepop/:lookup_key', (req, res) => {
let connection = mysql.createConnection({
//commented out for stackoverflow
});
connection.connect();
connection.query('SELECT * FROM table_incoming_leads WHERE leadid = '+req.params.send_key, (err, response, fields) => {
if (err) console.log(err);
res.json({
email: response[0].email,
first_name: response[0].first_name,
last_name: response[0].last_name
})
});
connection.end();
})
app.listen(port, () => console.log(`Server listening on port ${port}`));
/etc/nginx/sites-available/default
server {
root /var/www/html;
location / {
proxy_pass http://localhost: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;
try_files $uri $uri/ =404;
}
location /pretest {
proxy_pass http://localhost: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;
try_files $uri $uri/ =404;
}
location /prepop {
proxy_pass http://localhost: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;
try_files $uri $uri/ =404;
}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/subdomain.mydomain.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/subdomain.mydomain.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = subdomain.mydomain.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80 ;
listen [::]:80 ;
server_name subdomain.mydomain.com;
return 404; # managed by Certbot
}
You need to remove try_files directive from /prepop location because when nginx receives a request for let's say /prepop/somekey it looks for a file with that name (somekey) in your root directory. Since there is no such file it returns 404.

Mixed Content Error : This request has been blocked; the content must be served over HTTPS in MERN project on AWS

My project is deployed on AWS ec2 instance. After adding SSL to my domain I am start getting this error:
Mixed Content: The page at 'https://example.com/' was loaded over
HTTPS, but requested an insecure resource
'http://14.1.41.10/api/product/productsforcarousel'. This request has
been blocked; the content must be served over HTTPS.
This is a MERN project and problem is arrive after putting SSL. Here is my code:
const fs = require("fs");
const path = require("path");
const express = require("express");
const mongoose = require("mongoose");
const app = express();
mongoose
.connect(`mongodb+srv://${process.env.DB_URL}`, {
useNewUrlParser: true,
useUnifiedTopology: true,
useFindAndModify: false,
})
.then(() => {
app.listen(5000);
})
.catch((err) => {
console.log(err);
});
And here is nginx code
server {
listen 80 default_server;
server_name example.com www.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
root /var/www/Example_Pro/public;
index index.php index.js index.html;
server_name example.com www.example.com;
ssl_certificate "/etc/nginx/ssl/ssl.crt";
ssl_certificate_key "/etc/nginx/ssl/private.key";
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 10m;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256";
location / {
proxy_pass http://127.0.0.1:8043;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_read_timeout 90;
proxy_buffering off;
proxy_redirect http://127.0.0.1:8043 https://example.com;
}
}

socket.io return Transport unknown error through nginx

I'm trying to connect to my Nodejs server by Nginx.
my server runs on port 3000 and my Nodejs client successfully connects to the server using https://example.com:3000, while https://example.com/socket.io returns:
{"code":0,"message":"Transport unknown"}
I used certbot for SSL certification and it configured my nginx.conf
this is Nginx .conf file for my socket.io server:
upstream nodesocket {
server 127.0.0.1:3000;
}
server {
listen 443 ssl;
server_name example.com www.example.com;
access_log /var/log/nginx/access-ssl.log;
error_log /var/log/nginx/error-ssl.log;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers RC4:HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
keepalive_timeout 60;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
large_client_header_buffers 8 32k;
location /socket.io/ {
proxy_pass https://nodesocket;
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;
}
}
and this is my socket io server:
const express = require('express')
const https = require('https')
const socketIo = require('socket.io')
var fs = require('fs')
var options = {
cert: fs.readFileSync('/etc/letsencrypt/live/example.com/fullchain.pem'),
key: fs.readFileSync('/etc/letsencrypt/live/example.com/privkey.pem'),
ca: fs.readFileSync('/etc/letsencrypt/live/example.com/chain.pem')
}
var app = express();
var server = https.createServer(options, app);
var io = socketIo(server);
server.listen(3000, function(){
console.log('listening on :3000');
});
I checked nodejs and nginx logs but there were no related logs and no error.
I had the exact same issue and this worked for me
I deleted proxy_http_version 1.1;
and here is my nginx.conf
location /socket.io/ {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_pass http://127.0.0.1:3000/socket.io/;
}

Error on reverse-proxy nodejs app with ngnix

I'm following a book Building Bots with node.js
I have a server with node.js node red and ngnix on line
I clone simple serve code from github
https://github.com/azure-appservice-samples/NodeJS-EmptySiteTemplate
When i tried to proxy in nginx I have this error:
Cannot GET /bottest
this is default directives for ngnix
# You should look at the following URL's in order to grasp a solid understanding
# of Nginx configuration files in order to fully unleash the power of Nginx.
# http://wiki.nginx.org/Pitfalls
# http://wiki.nginx.org/QuickStart
# http://wiki.nginx.org/Configuration
#
# Generally, you will want to move this file somewhere, and start with a clean
# file but keep this around for reference. Or just disable in sites-enabled.
#
# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
##
# Default server configuration
#
server {
#listen 80 default_server;
#listen [::]:80 default_server;
#server_name **************;
#return 301 http://$server_name$request_uri;
listen 80 default_server;
listen [::]:80 default_server;
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
server_name *****************;
# SSL configuration
#
#listen 443 ssl default_server;
#listen [::]:443 ssl default_server;
include snippets/ssl-*************.conf;
include snippets/ssl-params.conf;
# Note: You should disable gzip for SSL traffic.
# See: https://bugs.debian.org/773332
#
# Read up on ssl_ciphers to ensure a secure configuration.
# See: https://bugs.debian.org/765782
#
# Self signed certs generated by the ssl-cert package
# Don't use them in a production server!
#
# include snippets/snakeoil.conf;
root /var/www/html;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
server_name _;
location ~ /.well-known {
allow all;
}
location /nodered {
if ($scheme = http) {
return 301 https://$server_name$request_uri;
}
proxy_pass http://**************:1880;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location /hello1 {
proxy_pass ***************:1880;
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;
}
location /bottest {
proxy_pass **********:8181;
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;
}
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# include snippets/fastcgi-php.conf;
#
# # With php7.0-cgi alone:
# fastcgi_pass 127.0.0.1:9000;
# # With php7.0-fpm:
# fastcgi_pass unix:/run/php/php7.0-fpm.sock;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# Virtual Host configuration for example.com
#
# You can move that to a different file under sites-available/ and symlink that
# to sites-enabled/ to enable it.
#
#server {
# listen 80;
# listen [::]:80;
#
# server_name example.com;
#
# root /var/www/example.com;
# index index.html;
#
# location / {
# try_files $uri $uri/ =404;
# }
#}
this is my server.js code:
var express = require('express');
var bodyParser = require('body-parser');
var request = require('request');
var app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.get('/', function (req, res) {
res.send('This is my Facebook Messenger Bot - Whos Off Bot
Server');
});
// for facebook verification
app.get('/webhook', function (req, res) {
if (req.query['hub.verify_token'] ===
'whosoffbot_verify_token') {
res.status(200).send(req.query['hub.challenge']);
} else {
res.status(403).send('Invalid verify token');
}
});
app.post('/webhook', function (req, res) {
var events = req.body.entry[0].messaging;
for (i = 0; i < events.length; i++) {
var event = events[i];
if (event.message && event.message.text) {
if (event.message.text.indexOf('hi') > -1) {
sendMessageWithInitialOptions(event.sender.id);
}
}
}
res.sendStatus(200);
});
function sendMessageWithInitialOptions(recipientId) {
messageData = {
'attachment': {
'type': 'template',
'payload': {
'template_type': 'button',
'text': 'Pl. Select your options',
'buttons': [{
'type': 'postback',
'title': 'Schedule a Meetting',
'payload': 'SCHEDULE A MEETING'
}, {
'type': 'postback',
'title': 'Whos Off When',
'payload': 'WHOS OFF WHEN',
}, {
'type': 'postback',
'title': 'My Schedule',
'payload': 'MY SCHEDULE'
}]
}
}
};
sendMessage(recipientId, messageData);
};
function sendMessage(recipientId, message) {
request({
url: 'https://graph.facebook.com/v2.6/me/messages',
qs: { access_token: 'PAGE_ACCESS_TOKEN' },
method: 'POST',
json: {
recipient: { id: recipientId },
message: message,
}
}, function (error, response, body) {
if (error) {
console.log('Error sending message: ', error);
} else if (response.body.error) {
console.log('Error: ', response.body.error);
}
});
};
app.listen((process.env.PORT || 8181));
anyone can help me?
http://www.minvolai.com/blog/2014/08/Setting-up-a-Secure-Single-Node-Elasticsearch-server-behind-Nginx/Setting-up-a-Secure-Single-Node-Elasticsearch-server-behind-Nginx/
server {
listen 80;
server_name http://dev.nodejs.com/;
location / {
rewrite ^/(.*) /$1 break;
proxy_ignore_client_abort on;
proxy_pass http://localhost:3000;
proxy_redirect http://localhost:3000 http://dev.nodejs.com/;
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;
}
}
Please refer this link

Deploy Nginx, Socket IO, Linode 404 error

I have been struggling trying to deploy a NodeJS server as SocketIO server on Linode. I have deployed my Django projects that works fine and I have redirected a subdomain to talk to the node server listening on port 8002 of local host.
I get a 404 error in my nginx log.
"GET /socket.io/?EIO=3&transport=polling HTTP/1.1" 404 72 "-" "Dalvik/2.1.0 (Linux; U; Android 5.0.1; LG-D850 Build/LRX21Y)"
Here is my nginx config
server {
listen 80;
server_name www.domain.com;
location / {
proxy_pass http://127.0.0.1:8000;
}
location /static {
alias /home/exampledir/staticfiles;
}
access_log /home/exampledir/nginx-access.log;
error_log /home/exampledir/nginx-error.log info;
}
server {
listen 80;
server subdomain.domain.com;
location / {
proxy_pass http://127.0.0.1:8002;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
Here is my nodejs server file
var socket = require('socket.io');
var express = require('express');
var http = require('http');
var app = express();
var server = http.createServer(app);
server.listen(8002, '127.0.0.1');
var io = socket.listen(server);
var redis = require('redis');
var sub = redis.createClient();
sub.subscribe('notify');
io.on('connection', function(socket){
socket.on('join', function (data) {
...
});
});
//Grab message from Redis and send to client
sub.on('message', function(channel, message){
...
});
I have tried using CORS and stuff but it does not work just keeps giving me a 404. I have verified the node server is running at 127.0.0.1:8002
My android socket is connecting to
mSocket = IO.socket("http://subdomain.domain.com/);
Please help.
Try this config
server {
listen 80;
# Make site accessible from http://localhost/
server_name domain.com;
location / {
proxy_pass http://127.0.0.1:8000;
}
location / {
proxy_pass http://127.0.0.1:8000;
}
location /static {
alias /home/example-dir/staticfiles;
}
access_log /home/example-dir/nginx-access.log;
error_log /home/example-dir/nginx-error.log info;
}
server {
listen 80;
server_name subdomain.domain.com;
location / {
proxy_pass http://127.0.0.1:8002;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
access_log /home/example-dir/socketnginx-access.log;
error_log /home/example-dir/socketnginx-error.log info;
}

Resources