I have a weird problem while I try to make the same PUT request multiple times, it works for about 8,9 times but after I have to refresh the page to work again.
I use React with Node.js (using Sequelize) for request:
React code:
return await axios
.put(`${API_URL}/api/user/createUser`, {
id_game_table: gameTableId,
name: nickName,
})
.then((response) => {
return [response.data, null];
})
.catch((error) => {
return [null, error.response];
});
My Node.js body destructuring:
What my Node.js looks like:
And the requests I was making:
Here, we can see that the first 9 PUT request was a success - this can be seen even in Node.js - but after 9 PUT requests was made all requests that I made was just OPTIONS and no other request was made. As another mention, there is not output in console.
The config for Node.js:
const express = require("express");
const app = express();
const cors = require("cors");
const http = require("http");
const server = http.createServer(app);
const socketIo = require("socket.io");
const index = require("./routes/index");
const port = process.env.PORT || 4001;
app.use(express.json());
app.use(cors());
app.use(index);
app.use("/api/gameTable", require("./routes/gameTable.routes"));
app.use("/api/user", require("./routes/user.routes"));
const io = socketIo(server, { cors: { origin: "*" } });
server.listen(port, () => console.log(`Listening on port ${port}`));
Note: The socket connection doesn't matter, I know that I had this request limit behaviour as well when using Angular with Spring in the past (without socket).
Related
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
I'm making a basic restaurant ordering web app for fun/learning purposes using node/express for my backend and react as my frontend. I've based my app on a mix of various YT tutorials including the ones Dave Gray to structure my project.
Currently I'm at the stage where I'm trying to implement notifications using SocketIO (the idea that the server will push notifications down to the clients to notify them of certain events such as an order being made).
My current progress is here: https://github.com/kevin-rph-lee/noodlebox/tree/socket-notifications
The issue I'm having is I'm trying to figure out the best way to pass my SocketIO object down to one of my controllers (specifically the orders controller).
My current structure is:
server.js --> orders.js (route) --> ordersController.js (controller)
Currently in my main server.js file I have initialized the io object for SocketIO (as seen below)
require('dotenv').config();
const WebSocketServer = require("ws").Server
var http = require("http")
const express = require('express');
const path = require('path');
const PORT = process.env.PORT || 3001;
const app = express();
const morgan = require('morgan');
const cors = require('cors');
const corsOptions = require('./config/corsOptions');
const credentials = require('./middleware/credentials');
const cookieParser = require('cookie-parser');
// Creating a new socketio server
const server = require('http').createServer(app);
const io = require('socket.io')(server);
//Numbers of users connected. Initially 0
let clientsConnected = 0
io.on('connection', function(socket){
//Client connecting, incrementing client counter
clientsConnected++
console.log('Client connected. Total clients connected ' + clientsConnected)
//When a message is recieved from a client, echo it to all other clients connected
socket.on("message from client", (arg) => {
console.log('reieved')
console.log(arg)
// socket.broadcast.emit('message to client', arg)
// socket.to(1).emit('message to client', 'enjoy the game')
io.in(1).emit('message to client', 'enjoy the game')
});
socket.on("join", (userID) => {
socket.join(userID)
console.log('Rooms:')
console.log(socket.rooms)
});
socket.on("leave", (userID) => {
socket.leave(userID)
console.log('Rooms:')
console.log(socket.rooms)
});
//Deincrement the counter when the client disconnects
socket.on("disconnect", (reason) => {
clientsConnected--
console.log('Client connected. Total clients connected ' + clientsConnected)
});
})
// PG database client/connection setup
const { Pool } = require('pg');
const dbParams = require('./lib/db.js');
const db = new Pool(dbParams);
db.connect();
// Load the logger first so all (static) HTTP requests are logged to STDOUT
// 'dev' = Concise output colored by response status for development use.
// The :status token will be colored red for server error codes, yellow for client error codes, cyan for redirection codes, and uncolored for all other codes.
app.use(morgan('dev'));
app.use(credentials);
app.use(cors(corsOptions));
app.use(express.json()); // => allows us to access the req.body
//middleware for cookies
app.use(cookieParser());
if (process.env.NODE_ENV === 'production') {
//server static content
//npm run build
app.use(express.static(path.join(__dirname, 'client/build')));
}
console.log(__dirname);
console.log(path.join(__dirname, 'client/build'));
// Separated Routes for each Resource
const usersRoutes = require('./routes/users');
const refreshRoutes = require('./routes/refresh');
const menuItemsRoutes = require('./routes/menuItems');
const ordersRoutes = require('./routes/orders');
// Resource routes
app.use('/users', usersRoutes());
app.use('/refresh', refreshRoutes());
app.use('/menuItems', menuItemsRoutes());
app.use('/orders', ordersRoutes());
// All other GET requests not handled before will return our React app
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, '/client/build/index.html'));
});
server.listen(PORT);
I am now trying to figure out how to pass the io object down to my orders route, and then from the route to the controller.
Within server.js, to pass io down to the route it was thinking it would be something like...
app.use('/orders', ordersRoutes(io));
But within the order route itself I get stuck
order.js
const express = require('express');
const router = express.Router();
const ordersController = require('../controllers/ordersController')
const verifyJWT = require('../middleware/verifyJWT')
const verifyRoles = require('../middleware/verifyRoles');
module.exports = () => {
//Get order
router.route('/')
.get(verifyJWT, verifyRoles('user', 'admin'),ordersController.getOrders)
//Create order
router.route('/')
.post(verifyJWT, verifyRoles('user', 'admin'), ordersController.createOrder)
return router;
};
To receive the io object from server.js I'm thinking I would need to modify the module.exports line so it would look like:
module.exports = (io) = {
but at that point I'm stuck on how I can pass it down one more layer from the route file to the controller file. The idea is I want the io functionality (e.g broadcasting a SocketIO message) to be available to me within the controllers file. In particular I want the ability to broadcast a message when a certain axios request is made from a connected client (e.g broadcast a SocketIO message when an axios POST request is made to create an order).
I was hoping someone could help me out with a potential way to move forward, or let me know if I'm going down the completely wrong path.
Thank you
i having an issue while using node.js with apache on site.
if using http without SSL node.js with apache are working with my domain at env. file
If I remove the SSL code it runs fine, however with it I get a request to http://mydomain.io/socket.io/1/?t=XXXXXXXXX
but when i enable SSL with let encrypt
my site are working but connect with Node js + socket io having error 404
*Note it's not trying https, which causes it to fail.
I'm testing on chrome, firefox and edge still can't fix.
I apologize if this is a simple question, I'm a node/socket.io newbie.
Thanks!
Here my details code are working when using http | but not working using https with let encrypt domain
const pino = require('pino')
const https = require('https');
const { Boom } = require('#hapi/boom')
const fs = require('fs')
const chalk = require('chalk')
require('dotenv/config')
const express = require('express')
const socket = require("socket.io");
const { toDataURL } = require('qrcode')
const mysql = require('mysql');
require('dotenv').config();
const request = require('request');
const app = express()
const host = process.env.HOST ?? '127.0.0.1'
const port = parseInt(process.env.PORT ?? 3000)
app.use(express.urlencoded({ extended: true }))
app.use(express.json())
const ser = app.listen(port, host, () => {
console.log(`Server is listening on http://${host}:${port}`)
})
const io = socket(ser);
const db = mysql.createConnection({
host: process.env.DB_HOSTNAME,
user: process.env.DB_USERNAME,
password: process.env.DB_PASSWORD,
database: process.env.DB_DATABASE
});
db.connect((err) => {
if (err) throw err;
console.log('Mysql Connected...');
});
const sessionMap = new Map()
I've had a similar issue before, you need 2 Different servers, one for http, and one for https.
var usinghttps = false;
if(usinghttps) {
var options = {
key: fs.readFileSync("/etc/letsencrypt/live/us2.swordbattle.io/privkey.pem"),
cert: fs.readFileSync("/etc/letsencrypt/live/us2.swordbattle.io/fullchain.pem"),
};
httpsserver = https.createServer(options, app).listen(443);
}
server = http.createServer(app);
And then to create the socket.io server,
const io = new Server(usinghttps ? httpsserver:server);
This personally worked for me, not sure if it works on all apps.
I build a server & client.
the client is trying to connect to the server by socket however I'm getting the following error in the console :
Access to XMLHttpRequest at 'http://localhost:5000/socket.io/?EIO=4&transport=polling&t=NS2s-Z_' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
The server:
const express = require('express');
const socketio = require('socket.io');
const http = require('http');
const PORT = process.env.PORT || 5000;
const router = require('./router');
const app = express();
const server = http.createServer(app);
const io = socketio(server);
io.on('connection',(socket) =>{
console.log('[Server] We have new connection !!!');
socket.on('disconnect',()=>{
console.log('[Server] WeUser has left !!!')
});
});
app.use(router);
server.listen(PORT,()=>{
console.log(`[Server] has started listen on port ${PORT}`);
});
The client:
let socket;
const Chat= ({location}) =>{
const ENDPOINT ='localhost:5000';
const [name,setName] = useState('');
const [room,setRoom] = useState('');
useEffect(()=>{
const {name,room} = queryString.parse(location.search) // get url
socket = io(ENDPOINT);
//Update state with new name and room
setName(name);
setRoom(room);
console.log(socket);
// socket.emit('ERROR');
},[ENDPOINT,location.search]);
return (<h1>Chat</h1>);
}
At first, I was sure the problem was that the server isn't on the same port as the client request. But sadly it's not the case.
Edit:
I've changed both ports to be 3000 and it seems to work, however, with any other port it's not. Is there a way the client cant send ack to connection because of os permission
I had the same problem, you can try adding the transport on the client side, worked for me
const socket = io("localhost:5000", { transports: ["websocket"] });
Your express needs to enable CORS. Here is how. Install this package:
npm i cors
require it:
const cors = require('cors');
Then right below your const app = express();, paste this:
app.use(cors());
I'm writing a server and a client with Node.js, the server uses express and the client uses axios.
I'm trying to send an image file from the client to the server. I found somewhere here this bit of code for the client:
let file = fs.createReadStream(file_path);
let form_data = new FormData();
form_data.append("picture", file);
let post_config = {
method: "post",
url: SERVER_PICTURE_URL,
headers: {"Content-Type": "multipart/form-data"},
data: form_data
}
axios(post_config).then(_ => {console.log("sent");} );
But I can't figure out what's supposed to be on the server side. I've tried the most obvious solution, writing response.data or response.form to a file, but both are undefined.
Is there some parser I'm supposed to use? And if so, how?
I'm not sure about the client that you wrote, but in express, you need to use express-fileupload package for getting the picture from req.files
const express = require('express');
const fileupload = require("express-fileupload");
const app = express();
const port = 3000;
app.use(fileupload());
app.post('/picture', (req, res) => {
const files=req.files;
res.send(files)
})
app.listen(port, () => {
console.log(`app listening at http://localhost:${port}`)
})