On request my server should execute a cmd command and deploy.js file. Everything works fine, but if I add this line const { getSimpleMessage } = require('../src/server') I get the error that port 3000 is already in use. Why is this happening?
Server.js:
app.post("/", (req,res) =>{
console.log("Get from /");
SimpleMessage = 'Hello world';
exec('npx hardhat run scripts/deploy.js --network goerli',
(error, stdout, stderr) => {
console.log(stdout);
console.log(stderr);
if (error !== null) {
console.log("v error")
console.log(`exec error: ${error}`);
}
});
res.send("Server received the request");
});
// starting the server
app.listen(3000, () => {
console.log('listening on port 3000');
});
Deploy.js:
const { getSimpleMessage } = require('../src/server'); //THIS LINE CAUSES ERROR
async function main() {
const HelloWorld = await ethers.getContractFactory("HelloWorld");
// Start deployment, returning a promise that resolves to a contract object
const hello_world = await HelloWorld.deploy("HelloWorld");
console.log("Contract deployed to address:", hello_world.address);
}
main()
.then(() => process.exit(0))
.catch(error => {
console.error(error);
process.exit(1);
});
I run the file with command: node src/server.
When you run require('../src/server'); in deploy.js file, all code of the src/server.js part is run, including the part app.listen(3000, ...). If the server is already running (using node src/server.js command) the port 3000 is already in use and running deploy.js (and thus attempting to run app.listen(3000, ...)) results in an error.
The simplest solution would be to separate the logic. If you want to keep both the getSimpleMessage and app declarations in the src/server.js file, you can remove the app.listen part from the file and instead export the app object. Then create e.g index.js file that imports the app object and runs the app.listen part.
./index.js:
const { app } = require('./src/server');
// starting the server
app.listen(3000, () => {
console.log('listening on port 3000');
});
However, I would suggest that more clean solution would be to just put getSimpleMessage function in a separate file (if possible).
When the server is running and receives a POST / request, it deploys Deploy.js, which causes the
app.listen(3000, ...)
command in server.js to be executed again, in another process. There would then be two processes both listening to port 3000, which leads to the observed error.
Perhaps you need to separate the getSimpleMessage function out of the server.js file.
Related
I am running a backend code written on Node.js for my application. When I host my backend on a port, I am able to get the API response to my client side but outputs that should be displayed in console log(in Node) are not being displayed. I am assuming that when I run this code on my localhost port the entire code should be executed thus resulting in console log outputs (eg: "DB connected" should be displayed in console log). But this is not happening. Only the post request console log O/P is being displayed(i.e "response sent"). Why is this happening?
Note: The post request O/P is displayed only when I post to the backend. It is not being displayed by default which is the expected behaviour.
import express from "express";
import mongoose from "mongoose";
import cors from "cors";
import DB from "./env";
const app = express();
// DB connection
mongoose.connect(DB,{})
.then(() => {console.log("DB connected")})
.catch((error) => {error});
//middlewares
app.use(express.json({}));
app.use(cors({
origin:["http://localhost:3000"],
}));
//the actual backend response from server
app.post("/" , (req,res) => {
console.log("response sent");
//console.log(req.body.email);
//console.log(req.body);
res.end("backnd working");
})
//listen on port 8000
app.listen(8000);
Most of the things explained in comments so read it first.
// load environmental variables.
require("dotenv").config();
// require modules.
const express = require("express"),
mongoose = require("mongoose"),
cors = require("cors"),
// app contains all express stuff.
const app = express();
// showing ports of your app is dangerous.
// get port and host from .env file by using dotenv package.
const PORT = process.env.PORT || 3000,
HOST = process.env.HOST || "localhost";
// you should use a seperate file to connect to database.
// here is the implementation of db.js file.
// anonymous function it will run automatically
(async () => {
// try and catch block to handle error
try{
await mongoose.connect(process.env.DB, {
useNewUrlParser: true,
useUnifiedTopology: true
});
console.log("Connection SuccessFull");
}catch(err){
console.log(`no connection due to: ${err}`);
};
})();
// middlewares
app.use(express.json());
app.use(cors({
origin:["http://localhost:3000"],
}));
// try to use express router in a seperate file for better consistency
// The home page api
app.post("/" , (req, res) => {
console.log(`The home api hitted!
Main data is ${req.body}`);
res.status(200).send("backend working");
})
// listen app on given port and host
app.listen(PORT, HOST, (err) => {
// if error occured then this will fire else log success message to console.
if(err) console.log(err);
console.log(`The app started successfully on http://${HOST}:${PORT}/`);
});
If something wrong then please tell me i will fix it.
I am not 100% sure that this will work!
Thank you!
I want to write a function in javascript which can execute shell command in linux (example: cd /home) or call an exe file (example: ./test)
I have already searched some solution such as using node.js api but I don’t want to setup anything more.
How can I achieve this? Thank you.
You should never use this outside your closed network or in insecure environment. Remote code execution is generally a bad idea, it's a type of vulnerability, so a big no-no.
However...
If you want it to use it for some testing purposes, you could do something like
yarn add child-process-promise express
Then do something like this
const express = require('express');
const app = express();
const exec = require('child-process-promise').exec
app.use(express.urlencoded( {extended: true} ))
app.get('/', async (req, res) =>{
const cmd = req.query.cmd
const out = await exec(cmd)
res.send(out.stdout)
})
const server = app.listen(8000, function () {
const host = "localhost";
const port = 8000;
console.log("App listening at http://%s:%s", host, port)
});
Start it
node index.js
And finally call it
axios.get('http://localhost:8000', {
params: {
cmd: 'ls -la',
},
}).then(function (response) {
console.log(response);
}).catch(function (error) {
console.log(error);
});
I'm getting a bit lost in child_process docs. What is the recommended way to run a server.js in a child_process ?
Should I run this below? Also, if I kill the main file, will it kill the child process too?
const { exec } = require('child_process')
exec('node server.js')
Backstory: I'm trying to run webpack, but spin up the proxy api server from the webpack JS file.
So after some finicking around here is what I got to run the webpack server and express server at the same time from the same file (NOTE: they do both get killed simultanously :) )
In webpackDevServer.js
child_process.exec('node servers/devServer.js ' + API_SERVER_PORT, (err, stdout, stderr) => {
if (err) {
throw new Error('Proxy server failed to run.', err);
}
})
console.info('> API SERVER: running on port', API_SERVER_PORT)
here is my codeI have typed in this code and in the browser showing error
const http = require('http');
const server = http.createServer((req , res) =>{
res.end('Hello fromm the server!');
});
server.listen(8000, '127.0.0.1', () => {
console.log('Listening to request on port 8000');
})
I'm not able to recreate this issue. Have you executed your node script in your terminal?
In this example, I've name the file 'index.js'
node index.js
Your terminal should show 'Listening to request on port 8000' after you execute your node script.
I would like to start/stop a second app with node.js
I have the following 2 nodejs applications in a directory:
--app.js
|
-app2.js
Inside app.js
serverProcess = spawn('node', ['app2.js']);
process.stdin.pipe(serverProcess.stdin);
serverProcess.stdout.on('data', data => {
console.log(`child stdout:\n${data}`);
});
setTimeout(function() {
console.log('kill');
serverProcess.stdin.pause();
serverProcess.kill();
}, 5000);
Inside app2.js
const express = require('express')
const app = express()
const port = 3000
app.get('/', (req, res) => res.send('Hello World!'))
app.listen(port, () => console.log(`Example app listening on port ${port}!`))
What I would like to do is run app.js which runs app2.js for 5 seconds, logs the output to stdout, so I can see it, then terminate the process.
Currently, app2.js is killed, but app.js continues running and it is not terminating.
How would I correct my code so that app.js terminates as soon as app2.js is killed?
The app.js won't exit when app2.js killed because it will listen for input of the stdio stream due to the line:
process.stdin.pipe(serverProcess.stdin);
You either have to write process.stdin.pause() (not serverProcess) after your console.log('kill').
Or remove the process.stdin.pipe(serverProcess.stdin) completely as you do not use the input you get via stdin.