React- can't connect to server socket - node.js

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());

Related

Limit of making PUT request

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).

how to make socket io | node.js - with SSL working

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.

express http client connect to server , https client can't connect to server

I've made a server that works with http just fine. The server was up and I was able to connect to it with Chrome and Postman. When I switch the server to https, the server is up, but I can't connect to it with Chrome and Postman. the ssl keys were sign by certbot.
server.js
const https = require('https');
const app = require(__dirname+'/app');
const fs = require('fs');
const port = 80;
const options = {
cert: fs.readFileSync("ssl/v2/fullchain.pem"),
key: fs.readFileSync("ssl/v2/privkey.pem")
}
https.createServer(options, app).listen(port);
console.log(port);
app.js
const express = require('express');
const morgan = require('morgan');
const body_parser = require('body-parser');
const homepage = require(__dirname+'/routes/homepage');
const user = require(__dirname+'/routes/user');
const test = require(__dirname+'/routes/test');
const table = require(__dirname+'/routes/table');
const catalog = require(__dirname+'/routes/catalog');
const cart = require(__dirname+'/routes/cart');
const payment = require(__dirname+'/routes/payment');
const app = express();
app.use(morgan("dev"));
app.use(body_parser.json());
app.use(body_parser.urlencoded({extended: true}));
app.use("/", homepage);
app.use("/user", user);
app.use("/test", test);;
app.use("/table", table);
app.use("/catalog", catalog);
app.use("/cart", cart);
pp.use("/payment", payment);
module.exports = app;
... the server is up, but I can't connect to it with Chrome and Postman
It is not clear from your description how exactly you are trying to connect to the server but I assume that you'll try a simple https://example.com/.
const port = 80;
...
https.createServer(options, app).listen(port);
But based on your code you are trying to use HTTPS on the port reserved for plain HTTP (80) instead of using the default port for HTTPS (443). Thus, https://example.com/ will not work since this will try to use port 443 and you would need to explicitly specify a different port with https://example.com:80/. But the better option would of course to use the default port for HTTPS in the first place in your code, i.e. 443 instead of 80.

ExpressJS Routes + Websockets - Share Port

I have an https expressjs server with websockets (using the 'ws' package). As far as I understand sockets and ports, I should be able to add a route alongside the websocket connections. The main use-case is so that the server can be curled (none of the ws curl requests I've seen online worked.)
Unfortunately I only have 1 port to use for the server and websockets. How can I set this up so that app and server can both listen on the same port?
I've seen a few comments on SO that indicates that it can be done, but no code examples, or it's for very different packages.
I'm using the 'ws' package: https://www.npmjs.com/package/ws
const port = 8888;
const http = require('http');
const https = require('https');
const express = require('express');
const websocket = require('ws');
const app = express();
app.use( express.static('public') );
app.get('/curl', (req, res) => res.send('Hello World')).listen( port );
const httpsServer = https.createServer( credentials, app );
const wss = new websocket.Server({ server: httpsServer });
httpsServer.listen( port, function listening(){
console.log( 'listening on ' + port );
});
Currently I get the "EADDRINUSE" error since I'm using the same port for two 'servers'.
FOLLOW-UP
Express app doesn't need to also listen if another server is.
To curl https, you have to provide the cert details, or use the '-k' (insecure) method.
Your code shows you trying to start two servers on the same port.
This line creates a new http server and attempts to start it on port 8888:
app.get('/curl', (req, res) => res.send('Hello World')).listen( port );
These lines create a new https server and attempt to start it on port 8888 also.
const httpsServer = https.createServer( credentials, app );
httpsServer.listen( port, function listening(){
console.log( 'listening on ' + port );
});
You cannot do that. If you just want one https server that works for both your web requests and your webSocket (a common way to do things), then change your code to this:
const port = 8888;
const https = require('https');
const express = require('express');
const websocket = require('ws');
const app = express();
app.use( express.static('public') );
app.get('/curl', (req, res) => res.send('Hello World'));
const httpsServer = https.createServer( credentials, app );
const wss = new websocket.Server({ server: httpsServer });
httpsServer.listen( port, function listening(){
console.log( 'listening on ' + port );
});
which just removes the .listen(port) that operates on the app object because that will create an http server and start it on the 8888 port.

Issue with a 404 error using socket.io

I've recently gotten into socket.io, during a long-term project of mine. Which is probably why I am having such a hard time of it, because their "getting started" sections don't take into account you may already be deep into development of your own application. The main issue is it connecting, it won't do it, client-side that is.
I keep getting a 404 not found which is cause by CANNOT POST /socket.io/ Which it is right, it can't obviously, mainly because that is not where the socket.io location is (it is in node_modules per usual). Secondly if I create a route for this, it does absolutely nothing. So here is code initializing it:
/*jshint esversion: 6*/
const express = require('express');
const http = require('http');
const bodyParser = require('body-parser');
const path = require('path');
const expressValidator = require('express-validator');
const flash = require('connect-flash');
const session = require('express-session');
const passport = require('passport');
const db = require('./config/db');
// Init App
const app = express();
// Init http server
const server = http.createServer(app);
// init socket
const io = require('socket.io').listen(server);
Here is the clientside trying to connect to it:
if (window.location.hostname == 'playkog.net' || window.location.hostname == 'www.playkog.net') {
var port = 443;
} else {
var port = 8080;
}
var connected = false;
var socket = io.connect(window.location.hostname + ':' + port, { 'connect timeout': 5000 });
// Connection Successful
socket.on('connect', function () {
console.log('a user connected');
connected = true;
});
socket.on('disconnect', function () {
console.log('user disconnected');
connected = false;
});
I imagine I'll have to connect to a different port, however I'm not sure which, nor if that is my issue (or only issue). Of course be extremely new to this kind of stuff (amateur at best) some of these things just go right over my head.
Here is a screenshot of my console

Resources