Giving public access to chat server on node.js - node.js

Now I am learning node.js and created a simple chat server using node.js.
My code:
net = require('net');
var sockets = [];
var s = net.Server(function(socket) {
sockets.push(socket);
socket.on('data', function(d) {
for (var i = 0; i < sockets.length; i++) {
if(sockets[i] == socket) continue;
sockets[i].write(d);
}
});
socket.on('end', function() {
var i = sockets.indexOf(socket);
sockets.splice(i, 1);
});
});
s.listen(8000);
How can I share this chat server on the Internet, so other people can use it?
On my local machine, I have an access through telnet:
telnet localhost 8000

If you really want to let others use this chat through telnet over the internet (which I recommend against), you will need to forward a port through your router (I assume you use a router) to port 8000 on your local machine. Give your friends your IP address and the port you mapped, and they should be able to telnet in as well.
It's hard to answer this question without more information, however. Do you use a firewall? Modem? Etc.

Its really hard to answer this question based on all the information.
It all depends if you are behind a router, firewall etc. If you are directly connected to the internet through a modem you can use ipconfig(in command prompt) to find your public ip. If you are behind a network router you will most likely have to setup port forwarding. If this is the case, just do a Google search on your router, I'm sure you will find a tutorial to set it up or you can refer to your manual.
Here is a explanation on port forwarding: http://en.wikipedia.org/wiki/Port_forwarding
Hope this helps or points you in the right direction!
EDIT 2022:
Easiest option these days would be to use NGROK (or something similar)

Related

Express.JS server to connect to host on remote network

So I got this small express server running. I can connect it to other devices on my local network e.g. mobile and other PC.
However when connecting over my 4g it does not work. Is there any reason for this? I am sure when I ping other private addresses on remote networks it has worked before, why not now?
Code:
const express = require("express");
const server = express();
const PORT = 3000
server.use(express.static("static"));
server.get("/", (req,res)=>{
res.sendFile(__dirname + "/pages/index.html")
});
server.listen(PORT, "0.0.0.0", (req,res) => {
console.log("Listening on port ", PORT)
});
Any information would be apricated I have some networking experience (still a noob just studying) and this really does interest me.
I assume you are trying to reach the server via your local IP. But you are doing it with 4G (in your phone maybe), which means your request is going over the internet while your local IP is only valid in your network.
Even if you are using your public IP, you would probably have to configure port forwarding on your router for it to know how to handle the incoming traffic for this port.
If you host your express server in your private network , you must have access to the express server by create port forwarding, destination nat, or some kind of publishing private services to public world methods.
If you need more help , i need to know more about your network env , your public ip and ...
Feel free to ask
An have a productive day

How to listen to multiple urls with Diet.js?

The documentation for Diet.js demonstrates a basic web server as:
var server = require('diet');
var app = server();
app.listen('http://localhost:8000');
app.get('/', function ($) {
$.end('Hello World!');
});
The above code snippet only listens to localhost on port 8000. However, If I would want the server to listen to requests with domain as localhost as well as the ip-address (and probably even the machine name), is there a way to do it? I think there isn't, at least as per the developer's documentation but it would be great if someone could point to me a decent hack of some sort.
You can change:
app.listen('http://localhost:8000');
to:
app.listen(8000);
or:
app.listen('http://0.0.0.0:8000/');

NodeJs text file writing

I am trying to write a text file from NodeJs. I have server running on my laptop. Currently, i am running client on my laptop and it works fine. But if i run same NodeJs client on Linux running on raspberrypi, it doesn't write on file or neither it gives any error.
I have the following code for client
var ioC = require('socket.io-client'),
ioClient = ioC.connect('http://localhost:4000'),
fs = require('fs'),
os = require('os');
ioClient.on('connect', function () { console.log("socket connected"); });
ioClient.on('ChangeState', function(msg){
console.log(msg);
fs.writeFile('server.txt', JSON.stringify(msg), function (err){
if (err) return console.log(err);
});
});
Can anybody please help me what can be the issue with this?
You are connecting to localhost which won't work if the client is on a different machine. You need to change the server to listen to the ip address your server has in your network, and also need to let your client connect to this ip. You can get the ip by running ifconfig in your terminal. Then (depending on wireless or wired connection) look for something like (usually the last paragraph):
and create the server on this ip. E.g.
192.168.178.30:4000
and connect to the same address from your client.
To find your ip on windows, refer to this guide

Allow Public IP to connect via WebSockets

I tried to creating a chat with nodejs ws (einaros),this is my code:
Server:
var WebSocketServer = require('ws').Server;
var wss = new WebSocketServer({ port: 80 });
wss.on('connection', function(ws) {
console.log('connecting count:' + wss.clients.length);
});
Client:
var hostname = location.hostname;
var port = 80;
var url = 'ws://'+hostname+':'+port+'/';
window.WebSocket = window.WebSocket || window.MozWebSocket;
var w = new WebSocket(url);
when I test with my computer or some other computers who connect with my router, it works well. However, other clients who visit via Internet cannot make the connection. Of course, they use the public IP, like 218.xxx.xxx.xxx, not 192.168.xxx.xxx.
I wonder how to solve this problem.
Thank you for you answer. But, it may be not the NAT problem. For example, My public IP is 218.100.50.50,and My private Ip is 192.168.1.1. When a connection comes from outside my network and visits 218.100.50.50:80, the router will redirect it to 192.168.1.1:80. There's a web page which can be visited in this way, but still cannot make the connection to my websocket server. This problem really confuses me much.
Sitting behind router with IPv4 leads to problems for routing actual traffic to right direction (computer behind router).
You need to Forward port 80 in router settings to your computer IP. Additionally I would recommend set in router settings preferred IP for your computer so after restart it is more likely not to change local IP address (otherwise can happen).
After those changes, you can even try to connect using Public IP from your own computer, and if it will work - then it should work from external computers.
Additionally check firewall settings to make sure it does not blocks any external traffic to port 80.
Your problem is called NAT: http://en.wikipedia.org/wiki/Network_address_translation
When a connection comes from outside your network (that is, against your public IP), the router doesn't know who's going to receive that connection. Imagine there are 3 PCs and 2 smartphones connected to your router, which one is going to "answer"? Well, what you have to do is tell the router: "dear router, when my friends try to connect on port 80, redirect them to device 192.168.1.37 and port 80 (for example)".
And if you don't want to reconfigure your router again and again to update 192.168.1.37 (because of DHCP random IP assignation) then tell your router to assign the same IP to your PC always (static ip).
So, configure a "static IP" for your PC, and create a port forwarding rule for port 80 to redirect traffic to your server. You can search "server behind router configuration" for more details, there are thousands of tutorials.

Node.js: Cannot access server from different device on the same network

NOTE: There are some others who have had similar problems, but those were solved by fixing small tidbits in the code involving how the server was listening (in examples that I've seen they put '127.0.0.1' as an argument in http.createServer(...).listen(). However, I do not have the same issue.
When I try to connect to my node.js server from a different machine on the same LAN network, Chrome says that it cannot connect.
This is testtesttest.js
var http = require('http');
http.createServer(function(req,res) {
res.writeHead(200,{'Content-Type': 'text/plain'});
res.end('Working');
}).listen(3000);
When I try inputting 192.168.1.73:3000 (of course 192.168.1.73 is the ip of the machine that I'm running the server on) into the browser (Chrome, although I've tried other browsers as well and I have similar problems) of my other machine, it gives the error "Oops! Google Chrome could not connect to 192.168.1.73:3000". When I type the same address onto the local machine, it works fine.
I'm not exactly sure what to do. I honestly hope this is just a stupid mistake on my part (I'm sorry for possibly wasting your time) and not something that I have to go into my router for.
Thanks very much for any help.
Try changing this
.listen(3000);
to this
.listen(3000, "0.0.0.0");
Just putting this here in case it saves anyone else. I had this problem for two full days when trying to connect my phone to my local machine... and it was because the wifi on my phone was turned off.
I too had this problem.
I solved it by allowing "node.js" in the network group.
Solution : Allowing "node.js" through the private network windows firewall
a. Go to Control Panel
b. Go to Windows Firewall
c. Click on the Allow an app or feature through windows firewall in the left sidebar
d. Search for "Node.js : Server Side JavaScript" and make sure both public and private column box is marked tick for "NodeJS"
e. Click "OK" and you are done
Below is the step i followed which Worked
My server code
var http=require('http');
http.createServer(function(request,response){
response.writeHead(200,{'Content-Type':'text/plain'});
response.end('Im Node.js.!\n');
console.log('Handled request');
}).listen(8080, "0.0.0.0");;
console.log('Server running a http://localhost:8080/');
Added inbound Rules.
Created a udp inbound rule(since i could'nt find any http protocol).
Once created go to properties for the created rule.
Choose Protocols and Properties tab.
Choose any in Port Type. Click apply and Ok. Now i tried from other
machine it worked!!!
I think you need to set Port Type to any to make it work.
Thanks
You have to open 3000 port so that it can be accessed from remote machines. You can do that in iptables file. Use below command to open file
vi /etc/sysconfig/iptables
now add below line before the reject lines in that file
-A INPUT -p tcp -m tcp --dport 3000 -j ACCEPT
Now restart iptables service using below command
service iptables restart
Now you restart your server and try again. It should work..
Chances are your firewall settings block incoming request on port 3000. You may want to add firewall inbound rule on this port to allow access to it.
For me, the culprit was a VirtualBox Host-only Network interface. The presence of this network interface was causing ipconfig on the server to report 192.168.56.1 instead of the router assigned address of 192.168.1.x. I was accessing the wrong IP all along.
To remove the VirtualBox Host-only Network interface:
Open VirtualBox
Go to File>Preference>Network>Host-only Networks
Remove the offending adapter(s)
My problem was that, I have used IP assigned to my ethernet adapter instead of wifi adapter...
And it now works when I connect from any device.
http.createServer(function(req,res) {
res.writeHead(200,{'Content-Type': 'text/plain'});
res.end('Working');
}).listen(3000, "192.168.1.36");
I found my IPv4 address on network settings, then specify with listen fun. put also 3000 port. I can reach http://192.168.1.36:3000/ via my tablet which is connected same wifi.
You have to run that on the terminal:
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
Explanation here
Like what Umamaheswaran answered, a new inbound rule needs to be created. But instead of using the UDP protocol, I have to use TCP. My application runs on a Windows Server 2012. The Inbound Rules are set in Windows Firewall with Advanced Security, under Administrative Tools
I solved this using this algorithm. What it does is get all ip info from os.networkInterfaces, get all keys and loop trough it, filter by objects that contains family == "IPv4" and get it address value. After, it looks for '192.168.0.xxx' pattern and put it in possible_ip array. Any other ip will be pushed to other_ips array.
The export sentence is to turn it into a module js file.
import by import {get_ip} from ./your_path/name_of_your_file.js, or in common js const { get_ip } = require("./your_path/name_of_your_file.js");
Hop it helps
const os = require('os');
const _ = os.networkInterfaces();
// if common js use
// exports.get_ip = () => {
export const get_ip = () => {
let ips = [];
Object.keys(_).map(key => {
let ipv4_obj = _[key].filter(obj => obj.family === "IPv4")
let ipv4 = ipv4_obj[0].address
ips.push(ipv4)
})
let other_ips = []
let possible_ip = []
ips.map(ip => {
ip.includes("192.168.0.") ?
possible_ip.push(ip) :
other_ips.push(ip)
})
return { possible_ip, other_ips }
}

Resources