I really can't get socket.io to work after deployment.
Backend:
import * as dotenv from "dotenv";
import express from "express";
import mongoose from "mongoose";
import cors from "cors";
import bodyParser from "body-parser";
import { Server } from "socket.io";
dotenv.config();
const app = express();
app.use(bodyParser.json({ limit: "15mb", extended: true }));
app.use(bodyParser.urlencoded({ limit: "15mb", extended: true }));
app.use(cors());
app.get("/", (req, res) => res.send("My app API"));
const PORT = process.env.PORT || 5000;
const SOCKET_IO_PORT = process.env.SOCKET_IO_PORT || 5500;
let server = app.listen(SOCKET_IO_PORT, () => {
console.log("Socket.io server running on port :" + SOCKET_IO_PORT);
});
const io = new Server(server, {
cors: { origin: "https://myapp.pages.dev" },
});
mongoose
.connect(process.env.CONNECTION_URL)
.then(() =>
app.listen(PORT, () => console.log(`Server running on port : ${PORT}`))
)
.catch((error) => console.log(error.message));
Frontend:
socket.current = io("https://myapp-api-production.up.railway.app");
socket.current?.on(
"getMessage",
(...) => {
...
}
);
Browser network tab:
Request URL: https://myapp-api-production.up.railway.app/socket.io/?EIO=4&transport=polling&t=OO7eSMV
Request Method: GET
Status Code: 404
Response:
Cannot GET /socket.io/
Server deployment log:
Socket.io server running on port :5698
Server running on port :
7777
You're creating two separate HTTP servers (by calling app.listen() twice). It looks like your frontend code is targeting the Express server, and not the socket.io server.
My suggestion would be to just use one HTTP server listening on PORT:
let server = app.listen(PORT, () => {
console.log("Server running on port :" + PORT);
});
(and remove the call to app.listen() in the Mongoose then() handler).
Related
I have two different machines connect to same network.
I wanted to connect over LAN Network using LAN assigned IP address below is the simple demonstration
Socket Client (Reactjs, IP : 192.168.0.103) to Socket Server (Express, IP :192.168.0.114)
Problem :
Getting error : Access blocked by CORS (tried express 'cors' middleware but failed with no solution)
Here is Simple React Code which is working fine
import socketClient from 'socket.io-client';
const SocketServer = 'http://192.168.0.114:3000';
function App() {
var socket = socketClient(SocketServer, {secure: true});
socket.emit('client_connected', { payload: {
message: "react client is connected"
}});
return (
<div>
</div>
);
}
export default App;
And simple express code (which also working fine)
const cors = require('cors')
const express = require('express')
const bodyParser = require('body-parser')
const app = express()
const http = require('http')
const server = http.createServer(app)
const { Server } = require('socket.io')
const io = new Server(server)
app.use(bodyParser.urlencoded({extended: true}))
app.use(express.static('public'))
app.use(cors({
origin: '*'
}));
app.set('view engine', 'ejs')
app.get('/', (req,res) => {
res.sendFile(__dirname + '/index.html')
})
io.on('connection', (socket) => {
socket.on('client_connected', (message) => {
console.log(message)
})
})
server.listen(3000, () => {
console.log('listening on *:3000');
});
Error screenshot getting in Browser console on ReatJs
enter image description here
I tried setting up headers in express but getting same error
Any help will be appreciated
You need to configure cors in the socket server not express
take a look here to know more about the configuration https://socket.io/docs/v3/handling-cors/
configuration example
const io = require("socket.io")(httpServer, {
cors: {
origin: "https://example.com",
methods: ["GET", "POST"]
}
});
I'm new to full stacking and have a Create React App hitting a single /api/verify endpoint in an Express backend.
In dev, I proxy the backend in my frontend package.json with "proxy": "localhost:8081"
DevOps needs to deploying this to a GCP nginx env and I need to make the proxy path relative so we don't have to hard code the domain in the proxy.
I have create a .env.development and .env.production but I'm not sure how to use them correctly so a local yarn start proxies localhost:8081 and a production build proxies the real domain.
I have a typical, simple Express server.js but not sure how to tie it all together.
const cors = require('cors');
const express = require('express');
const bodyParser = require('body-parser');
require('dotenv').config();
const app = express();
var corsOptions = {
origin: 'http://localhost:8081',
};
app.use(cors(corsOptions));
app.use(express.json());
app.use(bodyParser.json());
app.disable('x-powered-by');
// parse requests of content-type - application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: true }));
// simple route
app.get('/', (req, res) => {
res.json({ message: 'Welcome to bezkoder application.' });
});
require('./routes/gallery.routes')(app);
const PORT = process.env.PORT || 8081;
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}.`);
});
And my single route:
const { authJwt } = require('../middleware');
const galleryController = require('../controllers/gallery.controller.js');
module.exports = function (app) {
app.use(function (req, res, next) {
res.header(
'Access-Control-Allow-Headers',
'x-access-token, Origin, Content-Type, Accept',
);
next();
});
app.get(
'/api/verify',
[authJwt.verifyToken],
galleryController.fanPassGallery,
);
};
I'm following a tutorial for setting up a React application with MongooseDB, Express etc. I'm using Postman for GET, POST. See code below (I've starred the password from the database string).
When I send GET HTTP://localhost:8001 it shows "hello world" which I expect.
When I send GET HTTP://localhost:8001/tinder/cards it hangs and eventually displays the error "Error: socket hang up".
When I send POST HTTP://localhost:8001/tinder/cards it hangs and eventually gives a 500 Internal Server error.
Can anyone point me in the direction of where to debug please? I'm guessing the connection works as when I send GET HTTP://localhost:8001 it shows "hello world".
Thanks again.
import express from 'express'
import mongoose from 'mongoose'
import Cards from './dbCards.js'
import Cors from 'cors'
// App Config
const app = express();
const port = process.env.PORT || 8001
const connection_url = `mongodb+srv://admin:*******#cluster0.iyemf.mongodb.net/tinder-db?retryWrites=true&w=majority`
// middlewares
app.use(express.json())
app.use(Cors())
// db config
mongoose.connect(connection_url, {
useNewUrlParser: true,
useCreateIndex: true,
useUnifiedTopology:true,
})
// api endpoints
app.get('/', (req, res) => res.status(200).send("hello world"));
app.post('/tinder/cards', (req, res) => {
const dbCard = req.body;
Cards.create(dbCard, (err, data) => {
if (err) {
res.status(500).send(err)
} else {
res.status(201).send(data)
}
})
})
app.get("/tinder/cards", (req, res) => {
Cards.find((err, data) => {
if (err) {
res.status(500).send(err)
} else {
res.status(200).send(data)
}
});
});
// listener
app.listen(port, () => console.log(`listening on localehost: ${port}`));
You should also add the urlencoded middleware:
app.use(express.json());
app.use(express.urlencoded({
extended: true,
}));
I am using React and Express. Here is my code in Express.
const express = require("express")
const bodyParser = require("body-parser")
const { connection } = require("./db/connection")
const user = require("./routes/user")
const product = require("./routes/product")
const rentalHistory = require("./routes/rental-history")
const cors = require("cors")
const app = express()
app.use(express.static(__dirname + "/upload"))
app.use(bodyParser.urlencoded({ extended: true }))
app.use(bodyParser.json())
app.use(cors())
app.get("/", async (req, res) => {
res.json({ message: "Carbon Copies Rest Api" })
})
app.use("/user", user)
app.use("/product", product)
app.use("/rental-history", rentalHistory)
module.exports = { app }
When I hit this link https://carbon-copies-restapi.herokuapp.com/image_1628058210309.jpeg on the frontend. It throws this CORS Error. Other routes work just fine
I had the same issue, i solved adding 'origin: true' in the cors configuration.
app.use(cors({
origin: true
}))
I have a reactjs project and node.js project. Now i need to set up socket.io in my project. But after set i am getting 404 error. I tired using cross and other methods, but still i am getting the same 404 error. Thanks in advance
Index.js
const express = require("express");
const port = 3000;
const app = express();
const url = require("url");
var http = require('http').Server(app);
var io = require('socket.io')(http);
const origin = url.parse(`http://${process.env.CII_RESTURL || "localhost"}/`)
.origin;
var cors = require("cors");
app.use(cors());
var bodyParser = require("body-parser");
var path = require("path");
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
var router = express.Router();
app.set("port", port);
app.set("views", path.join(__dirname, "views"));
app.set("view engine", "ejs");
app.use(express.json());
app.use(express.static(__dirname + "./../../"));
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header(
"Access-Control-Allow-Headers",
"Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Requested-With"
);
res.header("Access-Control-Allow-Origin", req.headers.origin);
res.header('Access-Control-Allow-Credentials', true);
next();
});
// create a GET route
app.get("/express_backend", (req, res) => {
res.send({ express: "YOUR EXPRESS BACKEND IS CONNECTED TO REACT" });
});
app.use("/api", router);
var getTags = require("./routes/search");
router.get("/jobSearch", plainSearch.SearchByJob);
// console.log that your server is up and running
app.listen(port, () => {
console.log(`Listening on port: ${port}`);
console.log("Application live on the hostname: " + origin);
});
router.get("/",function(req,res){
res.send("hi")
})
//io.origins(cors());
io.on('connection', function(socket){
console.log("sd");
socket.on('subscribeToTimer', function(msg){
console.log('message: ' + msg);
});
});
React component
import io from 'socket.io-client';
const socket = io("http://localhost:3000/",{
path: '/api'
});
subscribeToTimer(cb) {
alert("sd");
socket.on('timer', timestamp => cb(null, timestamp));
socket.emit('subscribeToTimer', 1000);
}
calling the subscribeToTimer function in constructor.
It seems like you have not used the right react life cycle method to listen to the sockets. Always use componentDidMount() to listen to sockets or send API requests. Try something like this.
subscribeToTimer(cb) {
alert("sd");
socket.on('timer', timestamp => cb(null, timestamp));
socket.emit('subscribeToTimer', 1000);
}
componentDidMount(){
subscribeToTimer(cb);
}