The Heroku tutorial on creating/deploying a web- and a socketserver has the following piece of code setting up those servers:
const server = express()
//...
const wss = new SocketServer({ server });
In other words, one server runs for example at http://localhost:8080 and the other one at ws://localhost:8080. So the http server is referencing the socket server by:
var HOST = location.origin.replace(/^http/, 'ws')
var ws = new WebSocket(HOST);
//...
Now while I did not use the exactly same code, running both servers on the same address and port with the only difference being the protocol (http and ws) makes the websocket-server unreachable:
Firefox can’t establish a connection to the server at ws://localhost:8080/.
Changing the port to anything else fixes the problem. Why is that? And how should I implement my application, considering that Heroku recommends using static ports only as a fallback like
var port = process.env.PORT || 8080;
instead?
Related
I have a Node.js Socket.io v2.4 server that I want to restrict its access. I want only a particular chrome extension to be able to connect to it and nothing else. I noticed that traffic from Chrome Extension shows up as 127.0.0.1 as opposed to other traffic from localhost shows up as localhost. I know there are other ways like Interprocess Communication (IPC) that might be better than communication over websockets and http, but I can not use those at the moment.
Here are the pertinent parts of the node.js server code:
var express = require('express');
var path = require('path');
var app = express();
var server = require('http').createServer({
requestCert: false,
rejectUnauthorized: false
}, app);
var io = require('socket.io')(server);
var port = process.env.PORT || 3000;
//511 is backlog, which Specifies the max length of the queue of pending connections. Default 511
server.listen(port, '127.0.0.1', 511, function () {
console.log('[server] listening at port %d', port);
});
I thought this would only listen to requests from 127.0.0.1, but it seems to accept requests from any website loading in the browser.
Any help is most appreciated .. thank you
So the problem I'm having is that the client won't connect with the server.js when the server.js is using https.
if I go to "https://mydomainame.com" I get this error in the console of every other browser than brave browser
index.js:83 GET https://serverip:8081/socket.io/?EIO=3&transport=polling&t=NK0oCD6 net::ERR_CERT_AUTHORITY_INVALID
(The blacked out is the IP address of the server)
the weird thing is that in the brave browser the domain changes to "http://mydomainame.com" and the client then is connected to server.js
I'm using free Cloudflare with Full end to end encryption
server.js code:
var express = require('express'),
https = require('https');
var app = express();
var fs = require('fs');
var httpsOptions = {
key: fs.readFileSync('/var/www/ssl/sitename.com.key'),
cert: fs.readFileSync('/var/www/ssl/sitename.com.pem')};
var server = https.createServer(httpsOptions,app);
var io = require('socket.io').listen(server);
const port = 8081;
server.listen(port);
And client.js connection code:
socket = io.connect('https://serverip:8081', {secure: true});
I am using the same Origin Certificates for the server and for the nodejs code.
The server is using Apache2 with PHPMyAdmin and is configured to make the domain only work using https.
I read somewhere something Cloudflare not being able to use other ports than 443 and some other but I did not really understand it, And I can't get the server.js to work over port 443.
I'm thankful for any information or help I can get! :)
So I figured it out, big thanks to Eric Wong for pointing out the biggest problem that I was trying to connect to the server using its IP there for not going thru Cloudflare.
Then in this article Identifying network ports compatible with Cloudflare's proxy
you can see what ports Cloudflare allows connections on then, I changed my code to used the https port 8443.
socket = io.connect('https://domainname.com:8443',{secure: true});
then the only thing I had to do was to port forward the new port and everything worked fine!
I have created a chat app in node.js using port 4000. Everything works just fine, but when I rolled it out in production, I found that many corporate networks block outgoing port 4000. I considered using other ports that would be more likely to be open on a corporate network, but then found this list of ports blocked by chrome browser:
https://superuser.com/questions/188058/which-ports-are-considered-unsafe-by-chrome
Using ports such as 995 would result in a chrome error of "ERR_UNSAFE_PORT"
So it appears that the only ports allowed are 80 and 443 for a node.js server? What is the recommended best practice for choosing a port for your node.js application in a production environment?
My webserver is already using ports 80 and 443 for typical apache web serving. Do I need to create a dedicated server just for node.js?
I am using the following code to initiate the connection from the browser to the node.js server:
var socket = io.connect('https://duplex.example.com:4000');
and here is the code on the server side:
const https = require('https');
const fs = require('fs');
var express = require('express')
, bodyParser = require('body-parser');
var socket = require('socket.io');
var adminid = '';
var clientlist = new Array();
var port = 4000;
const options = {
cert: fs.readFileSync('./fullchain.pem'),
key: fs.readFileSync('./privkey.pem')
};
var app = express();
var server = https.createServer(options, app).listen(port, function(){
console.log("Express server listening on port " + port);
});
443 and 80 are the main ports for https and HTTP traffic respectively.
other ports can be used for WebSockets, but that doesn't sound like your use case.
What I have done in the past is use a reverse proxy, to discriminate on the incoming URL, and map the ports internally on my machine without the client needing to know.
NGINX is usually the easiest bet for this if you are on any sort of linux distro.
here is a blog about how to setup reverse proxy for a node app using nginx.
http://thejonarnold.com/configure-sails-js-with-subdomains-on-ubuntu/
the article references sailsjs, but there is nothing framework specific about the techique.
Most people don't expose their Node.js server directly to the internet but use Apache or Nginx as a frontend proxy.
Have your server bind to localhost only (or use firewall rules to only allow incoming 80 and 443.
server.listen('localhost', 4000)
Configure your reverse proxy. I'm using Caddy:
example.com {
root /var/www/example.com
# et cetera
}
duplex.example.com {
proxy / localhost:4000 {
websocket
}
}
When proxying websocket, you need to ensure the Connection and Upgrade headers aren't lost, which I've done with Caddy's shortcut here.
You could also use the same domain as the main site and only proxy a certain path.
Have the client socket.io connect to wss://duplex.example.com (on port 443). (I'm not familiar with socket.io to say why it uses an HTTPS URL instead of WSS, but I'll assume you have that working.)
I've got a problem to run the server with socketIO module on AWS EC2 server. My current code:
const port = process.env.PORT || 8080;
var server = require('http').Server();
var io = require('socket.io')(server);
const socketioHandler = require(backPath + 'functions/socketioHandler');
socketioHandler.ioConnections(io);
server.listen(port, 'ec2-IP_XXX.compute-1.amazonaws.com');
And the URI that I'm using to connect client to the server:
ec2-IP_XXX.compute-1.amazonaws.com:8080
It seams that for some reason the client cannot find the server.
This is the issue regarding the Security Group.
Security Groups has an Inbound rule, which is actually related to Port block or which all port should be open for the outside world.
So you have to open port 8080 for outside world.
So just add port 8080 (through edit option) in your inbound rules
So basically I have a webpage runned by apache on port 1900 and I have a NodeJS server running on port 3000.
Server code:
var express = require('express');
var http = require('http');
//make sure you keep this order
var app = express();
var server = http.createServer(app);
var io = require('socket.io').listen(server);
var port = 3000;
server.listen(port, '192.168.0.105', function(){
console.log('Server started: listening on port '+port+'.');
});
On the webpage a have the following code:
var socket = io('192.168.0.105:3000'); which connects to the NodeJS server when loading the page from the computer that runs the server(my laptop) and apache.
The problem appears when I try to access the webpage from another computer(laptop) connected to the same LAN that the laptop running the server is.
When I access 192.168.0.105:1900 from that laptop, I only see the page that is being loaded from apache but doesn't connect to the NodeJS server, it tries to connect to 192.168.0.105:3000 forever but fails after 1 minute.
How do I resolve this problem?
Thank you.
Making my comment into an answer since it solved the problem.
Windows 7 has a built-in personal firewall by default. You may have to enable connections to port 3000 manually. The router is presumably for access from outside the network. You're talking about accessing from your laptop when on the same LAN so that would more likely be the built-in personal firewall.