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}`)
})
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!
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.
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()
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.