How to run different server on same port? - node.js

I have created 2 server with express and node.js and now I want to run both the server on the same port which is localhost:8000 with different end points.
How it can be done or what can be the approach for it?
Attaching the server code for reference:-
Server1:-
const express = require("express");
const cors = require("cors");
const app = express();
const axios = require('axios');
app.use(cors());
process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = 0;
const PORT = 8000;
app.get("/WeatherForcast", function (req, res) {
axios.get('https://localhost:7173/WeatherForecast')
.then(response => {
res.status(200).json({ success: true, data: response.data});
})
.catch(error => {
console.log(error);
});
});
app.listen(PORT, function () {
console.log(`Server is running on ${PORT}`);
});
Server2:-
const express = require("express");
const cors = require("cors");
const app = express();
const axios = require('axios');
app.use(cors());
process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = 0;
const PORT = 8000;
app.get("/UserData", function (req, res) {
axios.get('https://localhost:7173/UserData')
.then(response => {
res.status(200).json({ success: true, data: response.data});
})
.catch(error => {
console.log(error);
});
});
app.listen(PORT, function () {
console.log(`Server is running on ${PORT}`);
});
Currently when I run it, one server runs and for other server an error is displayed that port 8000 is already in use.

You can't run two servers on the same port. The OS and TCP stack won't allow it.
The easiest solution is to use two endpoints on one server.
If you have to have two separate servers, then you would run them both on separate ports (neither of which is the public port) and then use something like nginx to proxy each separate path to the appropriate server.
So, the user's request goes to the proxy and the proxy examines the path of the request and then forwards it to one of your two servers based on the path of the request (as setup in the proxy configuration).

Two different servers can not be hosted on same port as it will give the error i.e "this port is currently is use" something like this.
The thing that can be done is instead of creating multiple server you can create a single server and define different endpoints to manage the code flow.

it is not possible to run different servers on same port

Related

How do I get user geo location from a node js(express) server?

I need to build a project to get user's country or location. With front-end user needs to give permission which could be bothersome for the API calls.
Is there any way to get an approximate location of the user from their IP address in node.js(express) server?
A solution could be to use APIs that return geoinformation for a given IP.
A sample could be this one which uses ip-api
const fetch = require('node-fetch')
const express = require('express')
const app = express()
const port = 3000
app.post('/location_specific_service', async (req, res) => {
var fetch_res = await fetch(`https://ipapi.co/${req.ip}/json/`);
var fetch_data = await res.json()
res.send(`You are from ${fetch_data.region}`)
})
app.listen(port, () => {
console.log(`Example app listening on port ${port}`)
})

Debian server, Node js Port 3000 listening But cant access via browser

On my debian server, I installed node and then started node server on port 3000. The server is running, but it isn't visible from the browser
Now when I try to get it running via my domain or via my ip(for example xx.xxx.xx.xx:3000) or my domain (my-domain.com:3000) in both cases it doesn't work. I think I don't quite get the concept and I tried to search for a billion different things, but I can't find the solution to my problem. Could someone tell me, if I need to setup something else, too?
My server js code is
const express = require('express');
const app = express();
const http = require('http');
const server = http.createServer(app);
const { Server } = require("socket.io");
const io = new Server(server);
server.listen(3000, () => {
console.log('listening on *:3000');
});
io.on('connection', function (socket) {
socket.on( 'new_message', function( data ) {
io.sockets.emit( 'new_message', {
message: data.message,
date: data.date,
msgcount: data.msgcount
});
});
});
Error i got
You need to listen for GET requests in order to respond to them.
Try adding something like:
app.get('/', function (req, res) {
res.send('GET request test.')
})
In your case make sure you add the route before passing the app to the http.createServer() method, or otherwise just use something like app.listen(3000).
More info in the docs: https://expressjs.com/en/guide/routing.html
why are you using express and http both packages.
you can run server by either of them.
and then add a get route for it.
import { createServer } from "http";
import { Server } from "socket.io";
const httpServer = createServer();
const io = new Server(httpServer, {
// ...
});
io.on("connection", (socket) => {
// ...
});
httpServer.listen(3000);
I hope this will work!

how can i host a website multiple times on nodejs?

const { response } = require('express');
const express = require('express');
const { request } = require('http');
const app = express();
app.listen(3000, () => console.log ('listening at 3000'));
app.use(express.static('public'));
app.use(express.json({limit: '1mb'}));
app.post('/api', (request, response) => {
console.log('Incoming data:');
console.log(request.body);
});
my code is here. my question in the title. how can i host public folder in the code more than one with different ports and ip's?
To my knowledge I do not believe it is possible to do this without creating lots of express servers which in my opinion is not best practice and may crash your server.
You may want to look at alternate solutions such as Nginx. You could setup Nginx virtual hosts to host multiple files.

Run Node JS server without port number

Can we run our node application without specifying any port number. And if we can do that so what are the ways to achieve that.
You do need a port number. A "port" is basically a mapping that will allow the OS to forward the incoming network packets to a specific process. So a server with no port is useless (or not a server).
What you can do instead, in order to find a port dynamically, is to use a module like portfinder.
As an example you can do this:
const express = require('express')
const portfinder = require('portfinder');
const app = express()
app.get('/', (req, res) => {
res.json({ok: 1})
})
async function main() {
const port = await portfinder.getPortPromise()
app.listen(port, () => {
console.log(`listening on port ${port}`)
})
}
main()

node.js server with websockets on elastic beanstalk ALB without socket.io

I'm trying to get a node.js server (using express) working using websockets in elastic beanstalk (EB) using application load balancer (ALB) but without using socket.io (because peerjs-server is the server I'm trying to get running and it's not written with socket.io).
I've seen a couple of articles suggesting you have to use socket.io (or another lib that doesn't just rely on websockets), but Amazon says ALB supports websockets directly.
My server is both a create-react-app server and a peerjs-server. It runs fine in dev on port 9000 for both the web UI and the peerjs ws connections.
I've tried all of the different approaches I've found, but I haven't gotten this to work, and I've even seen things written that suggest it can't be done, but it seems like I'm close. Has anyone gotten this to work, and if so, how?
Okay, I got it to work. Here's what I've done to get everything working on port 9000.
In EB, create an application, then begin creating an environment.
In the configuration of the environment, go into the Software section and tell it that you're going to use npm run prod to start your server.:
Now, go into the Load Balancers section and, as shown in the pic below:
add a listener on port 9000
create a process on port 9000 and enable stickiness (I called mine peerjsServer)
add Rules for each URL path you want to use to access the server, and have each of those rules assigned to the process you created (peerjsServer). Also point the default to that process, so that health checks on 80 get through successfully to your server
You may need to hop over to the EC2 dashboard in the AWS UI in order to make sure that the necessary Security Groups are defined there. I think I created the first two on the and the last two were default creations, but I don't recall. Anyway, they need to have port 9000 open for inbound and outbound (port 80 is there by default all the time):
Back to the EB configuration, go to the Instances section and make sure that your instance has the Security Groups assigned to it:
I ran react-scripts build to make the /build directory containing the production version of the server UI(this is create-react-apps stuff that I'm not covering here).
In my code, I start the server using a server.js that makes a server that runs both the peerjs-server ws server and an http server.
const express = require("express");
const bodyParser = require("body-parser");
const path = require('path');
const passport = require("passport");
const users = require("./routes/api/users");
const games = require("./routes/api/games");
const Game = require("./src/models/Game");
const WebSocket = require('ws');
const ExpressPeerServer = require('peerjs-server').ExpressPeerServer;
const app = express();
const url = require('url');
const port = process.env.PEERSERVERPORT || 9000;
// WebSocket for making db updates to client.
const wsserver = require('./wsserver').wsserver
// Server that gets all requests: lobby UI, peerserver, db websocket
const server = require('http').createServer(app);
wsserver.on('connection', function connection(ws) {
ws.on('message', msg => {
ws.send(msg)
})
ws.on('close', () => {
console.log('WebSocket was closed')
})
});
server.on('upgrade', function upgrade(request, socket, head) {
const pathname = url.parse(request.url).pathname;
if (pathname === '/ws') {
wsserver.handleUpgrade(request, socket, head, function done(ws) {
wsserver.emit('connection', ws, request);
});
}
});
// Bodyparser middleware
app.use(
bodyParser.urlencoded({
extended: false
})
);
app.use(bodyParser.json());
// Passport middleware
app.use(passport.initialize());
// Passport config
require("./config/passport")(passport);
// Routes -- the /api/* path is defined in the EB load balancer
app.use("/api/users", users);
app.use("/api/games", games);
// This is the create-react-apps /build directory of UI code
app.use(express.static(path.join(__dirname, 'build')));
app.get('/login', function (req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
// These are the paths that are defined in the EB load balancer
app.get('/logout', function (req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
app.get('/register', function (req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
app.get('/dashboard', function (req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
// Peer server for making WebRTC connections between game clients.
const options = {
debug: true
}
const peerserver = ExpressPeerServer(server, options);
app.use('/peerserver', peerserver);
app.use(express.static(path.join(__dirname, 'src')));
app.get('*', function(req, res) {
res.sendFile(path.join(__dirname, 'src', 'index.html'));
});
peerserver.on('disconnect', (client) => {
console.log('Delete the game if the host client disconnects');
Game.deleteMany({ hostPeerId: client })
.then(() => {
wsserver.clients.forEach(function each(client) {
if (client.readyState === WebSocket.OPEN) {
client.send("refreshGames");
}
})
})
.catch(err => console.log(err));
});
server.listen( port, () => console.log(`Server is up and running on port ${port} !`))
And then in my package.json, I set the script for prod to run the above server.js to start the server, and the npm run prod I put in the Software section earlier is what calls this to make the server go:
...
"scripts": {
"start": "set PORT=8081&& react-scripts start",
"prod": "node server.js",
...
After doing all that, I now have a running EB server using ALB and handling both websocket (ws) and UI (http) traffic on port 9000.

Resources