connecting react frontend and express backend using socket.io - javascript

I have one frontend made in React, running on port 3000 and one express/node server running on port 5000, both of them on the same computer (no network used).
I try to make them communicate using socket.io for the backend and socket.io-client for the frontend.
The connexion works somehow, but I have some error message in the frontend console, namely :
Access to XMLHttpRequest at 'http://localhost:5000/socket.io/?EIO=4&transport=polling&t=OMmsufE' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
polling.js:334
GET http://localhost:5000/socket.io/?EIO=4&transport=polling&t=OMmsufE net::ERR_FAILED 200
here's the front end code, App.js :
import './App.css';
function App() {
const socket = require('socket.io-client')('http://localhost:5000/socket.io/');
socket.on('connect', () => {
console.log('Connected to server');
socket.on('message', (message) => {
console.log('Received message:', message);
});
socket.emit('message', 'Hello, server!');
});
socket.on('disconnect', () => {
console.log('Disconnected from server');
});
return (
<div className="App">App
</div>
);
}
and the backend index.js :
const express = require('express');
const app = express();
const server = require('http').Server(app);
const io = require('socket.io')(server);
const cors = require("cors")
app.use(cors({ origin: 'http://localhost:3000' }));
io.on('connection', (socket) => {
console.log('User connected');
socket.on('disconnect', () => {
console.log('User disconnected');
});
socket.on('message', (message) => {
console.log('Received message:', message);
io.emit('message', message);
});
});
app.use("/socket.io/", (req, res, next) => {
next()
})
app.get("/", (req, res) => console.log("hello"))
app.use(cors())
server.listen(5000, () => {
console.log('Server listening on port 5000');
});
Anyone having an idea ?

so, indeed, as Konrad said, the problem came from the frontend, and especially this line :
const socket = require('socket.io-client')('http://localhost:5000/socket.io');
which was necessary to turn into, as Konrad said :
const socket = require('socket.io-client')('http://localhost:5000/);
but also, it was necessary to add :
const socket = require('socket.io-client')('http://localhost:5000/', {transports: ['websocket'], upgrade: false});
and now it works

I'm pretty sure that your socket.io endpoint is blocking the true endpoint
Client:
// remove `socket.io` here
const socket = require('socket.io-client')('http://localhost:5000/');
Server:
const express = require('express');
const app = express();
const server = require('http').Server(app);
const io = require('socket.io')(server);
const cors = require("cors")
app.use(cors({ origin: 'http://localhost:3000' }));
io.on('connection', (socket) => {
console.log('User connected');
socket.on('disconnect', () => {
console.log('User disconnected');
});
socket.on('message', (message) => {
console.log('Received message:', message);
io.emit('message', message);
});
});
app.get("/", (req, res) => console.log("hello"))
app.use(cors())
server.listen(5000, () => {
console.log('Server listening on port 5000');
});

Related

How can I get Socket.io to connect again?

In my Node.js backend I have the following code which is supposed to set up the Socket.io connection:
const express = require("express");
const app = express();
const { createServer } = require("http");
const httpServer = createServer(app);
const port = 3001;
const io = require("socket.io")(httpServer, { cors: { origin: "*" } });
io.on("connection", (socket) => {
console.log("Connected!");
socket.on("join-room", (id) => {
socket.join(id);
console.log(`user joined room ${id}`);
});
});
Previously this was working, but for some reason it isn't anymore. When I started my server today I wasn't able to get Connected! logged to the console, nor was user joined room logged to the console when that event was triggered. Is there something wrong with how I'm establishing this connection?

How to call ws WebSocket and wait for response in Express.js?

I have setup Nodejs to serve an HttpServer using ExpressJs. I also need to use ws WebSocket in order to connect to my device for fetching data.
My attempt is now this.
import express from 'express';
import cors from 'cors';
import http from 'http';
import { WebSocketServer } from 'ws';
const app = express();
app.use(cors());
//initialize a simple http server
const httpServer = http.createServer(app);
const wsServer = new WebSocketServer({ port: 7777});
wsServer.on('connection', function connection(ws, req) {
app.get('/', (req, res) => {
ws.send('{"msg":"getdata"}');
ws.on('message', function message(data) {
data = JSON.parse(data);
res.json(data);
});
});
//start our server
httpServer.listen(7778, () => {
console.log(`Server started on port ${httpServer.address().port} :)`);
});
});
The problem is that when the API is called more than once. An error code: 'ERR_HTTP_HEADERS_SENT' is thrown. I assume it is because the ws.on('message') is executed multiple times. So, I am trying to find a way to remove the listener but to no avail.
Is there any better way to do this? I just want to have a webserver that calls to another websocket in order to get data from a device.
For your code example to work, message on websocket must be sent after the / request is made. Because, before that, on message handler is not registered. Also, once handling the first request successfully, you cannot send a websocket message again. Because, when you do that, the res in the message handler is already completed. So, you will get ERR_HTTP_HEADERS_SENT. Thus proved :-)
So, your API calls must be like in the following pattern
/ Call #1
Websocket message #1
/ Call #2
Websocket message #2
If you do so, you will not get the ERR_HTTP_HEADERS_SENT error. Because, res is send once for every / request.
this will solve your error code: 'ERR_HTTP_HEADERS_SENT'
wsServer.on('connection', function connection(ws, req) {
app.get('/', (req, res) => {
//first This
ws.on('message', function message(data) {
data = JSON.parse(data);
res.json(data);
});
//then use this
ws.send('{"msg":"getdata"}');
});
//start our server
httpServer.listen(7778, () => {
console.log(`Server started on port ${httpServer.address().port} :)`);
});
});
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var timeout = require('connect-timeout');
var uuid = require('uuidv4');
var _ = require('lodash');
app.use(timeout('10s'));
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html');
});
let responses = []
io.on('connection', (socket) => {
socket.on('res', (e) => {
var obj = _.find(responses, r => r.id === e.id);
obj.res.send(e)
_.remove(responses, r => r.id === e.id);
})
})
app.get('/endpoint', (req, res) => {
const id = uuid()
io.emit('req', { id, ip: req.ip, header: req.headers, method: req.method });
responses.push({ id, res })
});
http.listen(3000);
If you want over multiple instance, you can use redis pub sub.

socket io client not connecting to server using ipv4 address

I'm having a problem with testing the connection when I use https://localhost:3000/ it connects successfully but I want to use socket Io client on a different device on android application to be precise I searched it up and turns out localhost wont work I have to connect using ipv4 address well I tried it but didnt work - like this http http://192.168.XX.XX:3000 for example so what is the problem why doesnt it connect please help
server code:
var cors = require("cors");
const express = require("express");
const app = express();
const port = process.env.PORT || 3000 ;
const server = app.listen(port, () => {
console.log(`started on ${port}`);
})
const io = require('socket.io')(server, {
cors: { origin: "*" }
});
io.on('connection', (socket) => {
console.log('a user connected');
socket.on('message', (message) => {
console.log(message);
io.emit('message', `${socket.id.substr(0,2)} said ${message}` );
});
});
require("dotenv").config();
app.use(express.json());
app.use(cors());
//routes setup
const homeGetRoute = require("./routes/test.js");
app.use("/home", homeGetRoute);
app.use(cors());

NodeJS | working with two protocols in server

i would like to work with http protocol and websocket on my server, and i will explain:
i have a chat app and i have a login page and chat page.
i would like to use the http protocol on login page and websocket for my chat page.
and if the answer yes, can i do this ?
const express = require('express')
const http = require('http')
const app = express()
const server = http.createServer(app)
const io = socketio(server)
in.on('connection', (req,res) => {
//...
})
app.get('/',(req,res) => {
//...
})
server.listen(port, (req, res) => {
console.log('Server is listen on port ' + port)
})

SOCKET.IO LISTEN HTTPS

i had my app with http, but i want add https, but i don't know how enable https on socket.io. The problem when i replaced http in 'require('socket.io)(https ....)' socket.io launch 404 error.
const http = require('http').Server(app);
const io = require('socket.io')(http, { pingInterval: 2000, pingTimeout: 7000,});
var https = require('https');
var fs = require('fs');
io.on('connect', socket => {
socket.on('ask', function(msg) {
search
.query(msg, socket.user, socket.token)
.then(result => {
socket.emit('response', result);
})
.catch(err => {
console.log(err);
socket.emit('response', {
msg: { text: "Lo siento, no puedo entender eso " },
type: 'error',
});
});
});
skills.registerClient(socket, socket.user).catch(err => {
console.warn('Failed to register client', err);
});
});
const port = await global.db.getGlobalValue('port');
http.listen(port, () => {
console.log(`Server started on http://localhost:${port}`);
});
const sslPort = '1443';
const server = https.createServer(httpsOptions, app)
.listen(sslPort, () => {
console.log(`Https server on https://localhost:${sslPort}`);
});
I am Currently using this:
const fs = require('fs');
const options = {
rejectUnauthorized: true,
key: fs.readFileSync('<SSL KEY PATH>/privkey.pem'),
cert: fs.readFileSync('<SSL CERT PATH>/fullchain.pem')};
const app = require('https').createServer(options);
const io = require('socket.io')(app);
io.on('connection', socket => {
console.log("New Connection");
socket.on('ask', function(msg) {
//your code here
});
});
app.listen(<PORT>); //e. g. 8080, Integer
First, you need to create cert and key for ssl.
After key and cert are generated, you can code like the following:
const express = require('express')
const https = require('https')
const fs = require('fs')
const port = 8888
const cert = fs.readFileSync('/path/to/your_cert.cert')
const key = fs.readFileSync('/path/to/your_key.key')
const SSLOption = {
key, cert
}
app = express()
let server = https.createServer(SSLOption, app)
server.listen(port, () => {
console.log('server started on port: ' + port)
})
app.get('/', (req, res) => {
res.send('Working good...')
})
const io = require('socket.io')(server)
io.on('connection', (socket) => {
console.log(socket)
})
enter image description here
This is the error.
var httpsOptions = {
key: fs.readFileSync(path.join(__dirname + '/ssl/localhost-key.pem')),
cert: fs.readFileSync(path.join(__dirname + '/ssl/localhost.pem'))
};
This is my httpsOptions.

Categories

Resources