Getting error while integrating Socket io and cloudflare - reactjs

Server-side code:
const express = require("express");
const app = express();
const http = require("http");
const { Server } = require("socket.io");
const cors = require("cors");
app.use(cors());
const server = http.createServer(app);
const io = new Server(server, {
cors: {
origin: "http://localhost:3000",
methods: ["GET", "POST"],
},
});
io.on("connection", (socket) => {
console.log(`User Connected: ${socket.id}`);
socket.on("join_room", (data) => {
socket.join(data);
});
Client-side code:
import io from "socket.io-client";
const socket = io.connect("http://localhost:8080");
function App() {
const joinRoom = () => {
if (room !== "") {
socket.emit("join_room", room);
}
};
But getting the following error after hosting it to cloudflare which works fine in local.:
polling.js:311 GET http://localhost:8080/socket.io/?EIO=4&transport=polling&t=OKgPK3u net::ERR_CONNECTION_REFUSED
I tried giving different port but still facing the same problem. Can anyone please help me?

Related

create Websocket with custom NextJS server

I'm runnung NextJS application with a custom server to establish a websocket between the frontend and the custom backend.
Here is the custom server:
const express = require("express");
const next = require("next");
const emitter = require("./lib/eventEmitter");
const port = parseInt(process.env.PORT, 10) || 3000;
const dev = process.env.NODE_ENV !== "production";
const app = next({ dev });
const handle = app.getRequestHandler();
const server = express();
const http = require('http')
const socketIo = require("socket.io");
const wbServer = http.createServer(server)
const io = socketIo(wbServer);
io.on("connection", (socket) => {
console.log("client connected: ", socket.id);
});
app.prepare().then(() => {
server.all("*", (req, res) => {
return handle(req, res);
});
server.listen(port, () => {
console.log(`> Ready on http://localhost:${port}`);
});
});
Here is the frontend connection:
useEffect(() => {
(async () => {
let socket = io("http://localhost:3000");
socket.on("connected", () => {
console.log("Connected");
});
})();
});
but it's not connecting React is showing 404 error like this:
XHR GET http://localhost:3000/socket.io?EIO=4&transport=polling&t=ODFLYBM
[HTTP/1.1 404 Not Found 8ms]
The answer is listening to wbServer instead of server like this:
const server = require("http").Server(app);
server.listen(port, () => {
console.log(`> Ready on http://localhost:${port}`);
});

How to resolve the Socket.io error "ERR_NAME_NOT_RESOLVED

When I run my MERN Stack project on my localhost and get my app's render page, when I click on a button in my app, that button does and displays nothing. When I inspect my client-side render page, I see the following error:polling.js:311 GET http://%22http/socket.io/?EIO=4&transport=polling&t=O7Mtvxd net::ERR_NAME_NOT_RESOLVED. I don't know what it means, I searched the meaning on the internet but without success. Here is my backend index.js file:
const express = require('express')
const cors = require('cors')
const mongoose = require('mongoose')
require("dotenv").config()
const app = express()
const http = require('http')
const server = http.createServer(app)
const io = require('socket.io')(server)
const UserRoutes = require('./routes/User')
const AuthRoutes = require('./routes/Auth')
const PostRoutes = require('./routes/Post')
const PORT = process.env.PORT || 5000
const {MONGODB_URI} = require("./config")
app.use(cors())
app.use(express.json())
app.use((req, res, next) => {
io.req = req
req.io = io
next()
})
app.use('/api/auth', AuthRoutes)
app.use('/api/user', UserRoutes)
app.use('/api/post', PostRoutes)
require('./socket')(io)
mongoose
.connect(MONGODB_URI, {
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true,
})
.then(() => {
console.log('database connected')
server.listen(PORT, () => console.log(`server started on port ${PORT}`))
})
.catch((err) => console.log(err))
my backend socket.js file :
const User = require('./models/User')
const jwt = require('jsonwebtoken')
module.exports = (io) => {
io.on('connection', (socket) => {
if (io.req) {
socket.broadcast.emit('friend-login-status', { user_id: io.req.userId })
addSocketIdInDB(socket.id, io.req.userId)
socket.on('disconnect', () => {
socket.broadcast.emit('friend-logout-status', {
user_id: io.req.userId,
})
io.req.userId = null
})
}
})
}
async function addSocketIdInDB(socket_id, user_id) {
const user = await User.findById(user_id)
if (socket_id) {
user.socketId = socket_id
}
await user.save()
}
I looked on this question after this but without success. I work on Microsoft Edge .

Why is my socket.on callback function not working?

On my client side in my function componet Join.js I want to use socket.on to generate a room id so I can have voice rooms. The problem is that I cant get either socket.on call to work on my client side.
join.js
.
.
.
const SERVER = "http://localhost:3001";
const socket = io.connect(SERVER);
const createSession = (room) => {
room.preventDefault();
socket.on('connect', () =>{
console.log('client socket.on')
} )
socket.on('create-session-response', session_ID => {
console.log(session_ID)
})
socket.emit("create-session", guest);
}
Server file
var express = require('express');
const path = require('path');
const bodyParser = require('body-parser');
var cors = require('cors');
const http = require('http');
const socket = require('socket.io');
const server = http.createServer(app);
const io = socket(server, {
cors: {
methods: ['GET', 'POST'],
},
});
// Listening for incoming connections
io.on('connection', (socket) => {
clientObject = undefined;
socket.on("create-session", (data) => { createSession(socket.id, data)});
socket.on("connect", () => {console.log("server side")})
.
.
.
});
I get this error repeatedly in the browser console:
polling-xhr.js:157 GET http://localhost:3001/socket.io/?EIO=4&transport=polling&t=O2crGvY net::ERR_CONNECTION_REFUSED

Issue fetching data with react

I have a rare issue fetching data on a useEffect hook....It gives me "CORS error" on chrome inspector... here is my code:
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import './HomeScreen.css'
import config from '../config'
// Compomnents
import Quiz from "../components/Quiz";
const HomeScreen = () => {
const [data, setData] = useState({ quizzes: [] });
const [loading, setLoading] = useState('true');
const [error, setError] = useState(false);
console.log("TESTING...............................");
useEffect(() => {
setLoading('testing');
const url = "https://mocki.io/v1/4a0ad1a9-352a-45bb-84b9-67e6363d6b7a"; //config.prodLocalhostURLRestAPI + 'quizzes';
fetch(url)
.then(res => res.json())
.then(res => {
setLoading('result..........')
})
.catch(error => {
//console.log(error);
});
}, []);
return (
<div className="homescreen">
<h2 className="homescreen__title">Quizzes</h2>
<div className="homescreen__quizzes">
<h2>{loading}</h2>
{loading ? <h2>Loading............</h2> : error ? <h2>ERROR</h2> : data.quizzes.map(quiz => (
<Quiz />
))}
</div>
</div>
)
}
export default HomeScreen;
The server code is:
var express = require("express"),
app = express(),
http = require("http"),
bodyParser = require("body-parser"),
methodOverride = require("method-override"),
server = http.createServer(app),
mongoose = require("mongoose");
const port = process.env.OPENSHIFT_NODEJS_PORT || 3011;
app.set('port', port);
app.set('ipaddr', process.env.OPENSHIFT_NODEJS_IP || "127.0.0.1");
app.use(bodyParser.json());
app.use(methodOverride());
//Import routes
const chatsRoutes = require('./routes/quizzes');
app.use('/quizzes/', chatsRoutes);
app.get('/', (req, res) => {
res.send("Ready!");
});
/** catch 404 and forward to error handler */
app.use('*', (req, res) => {
return res.status(404).json({
success: false,
message: 'API endpoint doesnt exist'
})
});
//app.use('/', routesRaids);
mongoose.connect('mongodb://localhost/quizes', {useNewUrlParser: true, useUnifiedTopology: true }, () =>
console.log('Connected to Mongo DB')
);
app.listen(port);
The URL is correct and works directly on the browser.
What's the issue?
First hit npm install cors , then
var express = require("express"),
app = express(),
http = require("http"),
bodyParser = require("body-parser"),
methodOverride = require("method-override"),
server = http.createServer(app),
mongoose = require("mongoose");
const cors = require('cors');
const port = process.env.OPENSHIFT_NODEJS_PORT || 3011;
app.use(cors())
app.set('port', port);
app.set('ipaddr', process.env.OPENSHIFT_NODEJS_IP || "127.0.0.1");
app.use(bodyParser.json());
app.use(methodOverride());
//Import routes
const chatsRoutes = require('./routes/quizzes');
app.use('/quizzes/', chatsRoutes);
app.get('/', (req, res) => {
res.send("Ready!");
});
/** catch 404 and forward to error handler */
app.use('*', (req, res) => {
return res.status(404).json({
success: false,
message: 'API endpoint doesnt exist'
})
});
//app.use('/', routesRaids);
mongoose.connect('mongodb://localhost/quizes', {useNewUrlParser: true, useUnifiedTopology: true }, () =>
console.log('Connected to Mongo DB')
);
app.listen(port);

HTTPS on localhost using NextJS + Express

System Information
Express: 4.16.4
NextJS: 8.0.3
React: 16.8.4
ReactDOM: 16.8.4
Goal
Serve the web application using SSL over HTTPS on localhost
What has been done
Created basic NextJS application using Create Next App
Generated a certificate and key using OpenSSL and moved it into the project directory
Added the Express dependency
Configured the app to use express inside server.js
Changed script to use the server.js inside package.json scripts.
server.js
const express = require('express');
const next = require('next');
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handle = app.getRequestHandler();
const port = 3000;
const https = require('https');
const fs = require('fs');
const httpsOptions = {
key: fs.readFileSync('./certificates/key.pem'),
cert: fs.readFileSync('./certificates/cert.pem')
};
app
.prepare()
.then(() => {
const server = express();
server.get('*', (req, res) => {
return handle(req, res);
});
server.listen(port, err => {
if (err) throw err;
console.log('> Ready on http://localhost: ' + port);
});
})
.catch(ex => {
console.error(ex.stack);
process.exit(1);
});
Extra Information
The app currently works when initialized using yarn dev. I have tried to serve the app over https using this answer but I was unable to figure out how to apply this to my current setup using NextJS.
I spent a lot of time researching the web how to apply this solution but have not yet found a way on how to make this work.
Any help is greatly appreciated.
You just need to use the createServer method of https module.
const { createServer } = require('https');
const { parse } = require('url');
const { readFileSync } = require('fs');
const next = require('next');
const port = 3000;
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handle = app.getRequestHandler();
const httpsOptions = {
key: readFileSync('./certificates/key.pem'),
cert: readFileSync('./certificates/cert.pem')
};
app.prepare()
.then(() => {
createServer(httpsOptions, (req, res) => {
const parsedUrl = parse(req.url, true);
handle(req, res, parsedUrl);
}).listen(port, err => {
if (err) throw err;
console.log(`> Ready on https://localhost:${port}`);
})
});
Other answer seemed to just drop express... Found a solution after some difficulty with both server code and certificate so hopefully can save someone else the trouble!
First of all, solid advice for creating localhost certificate here:
https://letsencrypt.org/docs/certificates-for-localhost/
Secondly, simple code that offers HTTP/HTTPS with next js and express:
const next = require('next');
const express = require('express');
const http = require('http');
const https = require('https');
const fs = require('fs');
const ports = {
http: 3080,
https: 3443
}
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handle = app.getRequestHandler();
const server = express();
const options = {
key: fs.readFileSync('localhost.key'),
cert: fs.readFileSync('localhost.crt'),
};
app.prepare().then(() => {
server.all('*', (req, res) => {
return handle(req, res)
});
http.createServer(server).listen(ports.http);
https.createServer(options, server).listen(ports.https);
});
It is worth noting that one could omit or redirect either port.
Below work for me very well for next server with https;
Using this official documentation of node js https module Creating HTTPS Server
const { createServer } = require('http')
const { parse } = require('url')
const next = require('next')
const { readFileSync } = require('fs');
const port = parseInt(process.env.PORT, 10) || 3000
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()
const httpsOptions = {
pfx: readFileSync('./certificates/AMB.pfx'),
passphrase: 'Testabc$'
};
app.prepare().then(() => {
createServer(httpsOptions, (req, res) => {
const parsedUrl = parse(req.url, true)
const { pathname, query } = parsedUrl
if (pathname === '/login') {
app.render(req, res, '/login', query)
} else {
handle(req, res, parsedUrl)
}
}).listen(port, err => {
if (err) throw err
console.log(`> Ready on https://localhost:${port}`)
})
})
Our straightforward, switchable implementation:
const app = require('express')();
const https = require('https');
const http = require('http');
const next = require('next');
const fs = require('fs');
const path = require('path');
const HTTPS = true;
const server = HTTPS
? https.createServer(
{
key: fs.readFileSync(path.resolve(__dirname, './server.key')),
cert: fs.readFileSync(path.resolve(__dirname, './server.cert')),
},
app
)
: http.createServer({}, app);
const port = parseInt(process.env.PORT, 10) || 3000;
const dev = process.env.NODE_ENV !== 'production';
const nextApp = next({ dev });
const nextHandler = nextApp.getRequestHandler();
nextApp.prepare().then(() => {
app.get('/api/something', (req, res) => {
res.json({});
});
// ...
app.get('*', (req, res) => {
return nextHandler(req, res);
});
server.listen(port, (err) => {
if (err) throw err;
console.log(`> Ready on http${HTTPS ? 's' : ''}://localhost:${port}`);
});
});

Resources