database.js
const mongoose=require('mongoose')
const connectDB=()=>{
mongoose.connect(process.env.DB,()=>{
console.log("CONNECTED TO DATABASE")
})
}
module.exports=connectDB
server.js
const app=require('./app')
const dotenv=require('dotenv')
const connectDB=require('./config/database')
dotenv.config({path:"config/dotenv.env"})
connectDB()
app.listen(process.env.PORT, () => {
console.log(`CONNECTED TO SERVER ON PORT : ${process.env.PORT} in ${process.env.NODE_ENV} mode `);
});
Now the DB inside my config.env file, even If I change it to the wrong string , to get promise rejection , I still get the "CONNECTED TO DATABASE" logged to the console.
It does not show the error, but the requests to routes in postman gets stuck on loading.
What's going wrong?
The callback you provide to the connect() function gets executed also if the connection fails.
This would prevent logging the message to the console in such cases:
const connectDB = () => {
mongoose.connect(process.env.DB, (error) => {
if (!error) {
console.log("CONNECTED TO DATABASE")
}
})
}
Related
I'm trying to make a way to boot up a Minecraft server from nodejs, but I'm having trouble making a way to run commands from nodejs.
const { spawn } = require('node:child_process')
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
const fs = require('fs');
app.get('/start', (req, res) => {
fs.writeFile('minecraftstatus.txt', 'on', (err) => {
if (err) throw err;
});
const command = spawn('java', ['-jar', '-Xms2048M','-Xmx2048M', '-Dfile.encoding=utf8', 'server.jar', 'nogui'])
// the `data` event is fired every time data is
// output from the command
command.stdout.on('data', output => {
// the output data is captured and printed in the callback
fs.appendFile('console.txt', ("\n" + output.toString()), 'utf-8', err => {
console.log(err)
})
console.log("Output: ", output.toString())
})
res.status(200).send("OK")
});
app.listen(80, () => {
console.log('Server started on port 80');
});
From what you see above, whenever a user sends a GET request, it sends a command and appends any output to a text file. I need to make a way in order to send commands to Minecraft. I need to send commands to the same shell that nodejs ran the command.
I've tried this:
app.get('/mcstop', (req, res) => {
try {
const command2 = spawn('/stop')
// the `data` event is fired every time data is
// output from the command
command2.stdout.on('data', output => {
// the output data is captured and printed in the callback
console.log("Output: ", output.toString())
})
res.status(200).send("OK")
}
catch {
console.log("Oh no...")
}
});
Where it sends /stop to the shell, but it seems like it isn't being ran on the same shell as where the Minecraft server was created from.
How could I achieve this?
I have tried to find a way from Google but the results can remain the same
http://localhost:8000/socket.io/?EIO=3&transport=polling&t=MnHYrvR
i try this wan medium try other ways, the results remain the same
and for the front end I have tried, socket io inside the hook component and outside the scope, the results remain the same
http://localhost:8000/socket.io/?EIO=3&transport=polling&t=MnHYrvR
this is my code from server:
app.prepare().then(() => {
const server = express();
const setServer = require('http').Server(server);
const io = require('socket.io')(setServer)
server.use(bodyParser.json());
server.use(cookieParser());
io.on('connection', socket => {
console.log('socket', socket);
socket.emit('now', {
message: 'zeit'
})
})
server.use(routers)
server.get('*', (req, res) => {
return handle(req, res);
});
server.use( (err, req, res, next) => {
console.log(err)
if(err.name === 'Error'){
res.status(401).send({
title: 'error',
detail: 'Unauthorized Access!'
})
}
})
server.listen(port, err => {
if (err) throw err;
console.log(`> Ready on http://heroku:${port}`)
})
})
.catch(ex => {
console.error(ex.stack);
process.exit(1);
});
from front end:
//at the top of function
const io = require('socket.io-client');
const socket = io.connect('http://localhost:8000');
console.log('socket', socket);
//in use effect
useEffect(() =>{
socket.on('now', message => {
console.log('message', meesage);
})
})
Please help
Although I am not using Next.js, I have a similar setup with Express.js that might help you with your problem...
On my Node.js side I have the following setup:
const app = require('express')()
const server = require('http').createServer(app)
const io = require('socket.io')(server)
// ...
io.sockets.on('connection', () => {
console.log(`Client with ID of ${socket.id} connected!`)
io.sockets.emit('SOME_EVENT', 'HelloWorld')
})
Then, my frontend with React looks like this:
import React from 'react'
import io from 'socket.io-client'
function useSocket(url) {
const [socket, setSocket] = useState(null)
useEffect(() => {
const socketIo = io(url)
setSocket(socketIo)
function cleanup() {
socketIo.disconnect()
}
return cleanup
// should only run once and not on every re-render,
// so pass an empty array
}, [])
return socket
}
function App() {
const socket = useSocket('http://127.0.0.1:9080')
useEffect(() => {
function handleEvent(payload) {
console.log(payload)
// HelloWorld
}
if (socket) {
socket.on('SOME_EVENT', handleEvent)
}
}, [socket])
return (...)
}
Also, one common error that I am seeing when working with socket.io is the following:
Cross-Origin Request Blocked: The Same Origin Policy disallows
reading the remote resource at
http://127.0.0.1:9080/socket.io/?EIO=3&transport=polling&t=MnH-W4S.
(Reason: CORS request did not succeed).
This is due an incorrect URL that's provided as a parameter in the socket manager creation process:
const socket = io('http://localhost');
So just double check that the address you're providing is correct. If you're serving your application on now and accessing it through a now.sh URL, but providing http://localhost as your URL parameter, then it won't work.
(I realise that this is an old/stale question, but in the spirit of "The Wisdom of the Ancients".)
I came across this question because I had the exact same problem. I realised that I was using the wrong server to listen with. Instead of Express, you should use the HTTP module.
const setServer = require('http').Server(server);
const io = require('socket.io')(setServer)
So, this part...
server.listen(port, err => {
if (err) throw err;
console.log(`> Ready on http://heroku:${port}`)
})
...should become:
setServer.listen(port, err => {
if (err) throw err;
console.log(`> Ready on http://heroku:${port}`)
})
The basic problem can be summarized as follows: When creating a Websocket server in Node using ws with the server option populated by an express server(as in this example), while using that same express server to handle the routing for NextJS (as in this example), the upgrade header seems to not be properly parsed.
Instead of the request being routed to the Websocket server, express sends back an HTTP 200 OK response.
I've searched high and low for an answer to this, it may be that I simply do not understand the problem. A possibly related question was brought up in an issue on NextJS's github. They recommend setting WebsocketPort and WebsocketProxyPort options in the local next.config.js, however I have tried this to no avail.
A minimal example of the relevant server code can be found below. You may find the full example here.
const express = require('express')
const next = require('next')
const SocketServer = require('ws').Server;
const port = parseInt(process.env.PORT, 10) || 3000
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()
app.prepare().then(() => {
const server = express()
server.all('*', (req, res) => {
return handle(req, res)
})
server.listen(port, err => {
if (err) throw err
console.log(`> Ready on http://localhost:${port}`)
})
const wss = new SocketServer({ server });
wss.on('connection', function connection(ws, request) {
console.log('Client connected');
ws.on('close', () => console.log('Client disconnected'));
});
wss.on('error', function (error) {
console.log(error);
});
setInterval(() => {
wss.clients.forEach((client) => {
client.send(new Date().toTimeString());
});
}, 1000);
}).catch(ex => {
console.error(ex.stack);
process.exit(1);
});
The expected result, of course, is a connection to the websocket server. Instead I receive the following error:
WebSocket connection to 'ws://localhost:3000/' failed: Error during WebSocket handshake: Unexpected response code: 200
Can anyone elucidate anything for me here?
Ok, after more digging I have solved the problem. Quite simply, the ws.Server object to which I was trying to feed the server = express() object is not strictly speaking an http server object. However, server.listen() returns such an http server object. On such an object we can listen for an 'upgrade' call, which we can pass to our ws.Server object's handleUpgrade() event listener, through which we can connect. I will be updating the examples that I linked in my question, but the relevant code is below:
app.prepare().then(() => {
const server = express()
server.all('*', (req, res) => {
return handle(req, res)
})
const wss = new SocketServer({ server });
wss.on('connection', function connection(ws, request) {
console.log('Client connected');
ws.on('close', () => console.log('Client disconnected'));
});
wss.on('error', function (error) {
console.log(error);
});
let srv = server.listen(port, err => {
if (err) throw err
console.log(`> Ready on http://localhost:${port}`)
})
srv.on('upgrade', function(req, socket, head) {
wss.handleUpgrade(req, socket, head, function connected(ws) {
wss.emit('connection', ws, req);
})
});
Background
Making a small web app that connects to a Mongo DB hosted with Mlab. I've created the DB on mlab, and created users with read/write permission. I've also created a users collection with several records.
The Problem
When I try and connect to the database using the code on mongo.github.io, I hit the error:
/home/ed/dev/mongo-demo/node_modules/mongodb/lib/operations/mongo_client_ops.js:466
throw err;
^
TypeError: Cannot read property 'db' of null
The Code
var MongoClient = require('mongodb').MongoClient;
const url = 'mongodb://<user>:<pass>#ds115434.mlab.com:15434';
// Database Name
const dbName = 'princee3-music';
// Use connect method to connect to the server
MongoClient.connect(url, function(err, client) {
console.log("Connected successfully to server");
const db = client.db(dbName);
client.close();
});
What I Have Tried
Oddly, if I connect through the shell using:
mongo ds115434.mlab.com:15434/princee3-music -u <dbuser> -p <dbpassword>
That works fine, or if I wrap the connection in an anonymous self-calling async function, it also connects.
Async Wrapper
const MongoClient = require('mongodb').MongoClient;
const mongoUrl = 'mongodb://<user>:<pass>#ds115434.mlab.com:15434/';
const dbName = 'princee3-music';
(async() => {
const client = await MongoClient.connect(mongoUrl, { useNewUrlParser: true});
const db = client.db(dbName);
db.collection('users').insertOne({
email: user.email,
pass: hashedPassword,
admin: true
}, (err, result) => {
if (err) {
reject({error: err});
} else {
resolve({message: 'okay'});
}
});
client.close();
})();
Any pointers on where I may be going wrong would be great.
The official mLab docs advise to connect like below. It has to be asynchronous , in order to wait for the connection to occur, or the client will be null, thus throwing an error saying that it can’t read property db of null.
On the other hand, you async has useNewUrlParser which might be the key to have a successful connection, see this issue
MongoClient.connect(url, { useNewUrlParser: true }).then(client => client.db())
Hiii,
Recently my elastic beanstalk server have started to become unresponsive and return's 504 gateway timeout. I suspect that my pool.connect is becoming unresponsive and there are no logs reporting error while connecting to pool but it stucks at connecting. My other controllers with no database query works fine.
This goes away when I restart the server but after some time same thing happens.
I making requests this way-
1) database.js
const pg = require("pg")
// setting timestamp for the postgres.
pg.types.setTypeParser(1184, function(stringValue)
{
console.log(stringValue)
return new Date(Date.parse(Date.parse(stringValue + "+0000")))
})
// configuration for postres for connecting.
const pgConfig = {
user: "USER",
database: "DATABASE",
password: "1234",
port: 5432
}
const pool = new pg.Pool(pgConfig)
module.exports = pool
2) somecontroller.js
const db = require("../database/database")
const constant = require("../utility/constant")
module.exports = function(req, res)
{
db.connect(function(err, client, done)
{
if(err)
{
done()
console.log(constant.error.db.CONNECT_CONSOLE, err)
return res.send({status: constant.status.ERROR, code: constant.error.db.CONNECT})
}
client.query("QUERY", [UID])
.then(result =>
{
// Processing this queries and Some other query.....
})
.catch(err =>
{
console.log(constant.error.db.QUERY_CONSOLE, err)
res.send({status: constant.status.ERROR, code: constant.error.db.QUERY})
})
done()
})
}
My every controller works in similar fashion.
Thanks,