Socket.io is not connecting to my Express.js server - node.js

I am trying to get Socket.io to connect to my Express.js server but I haven't been able to successfully connect them despite closely following the examples given on the Socket.io website and other code I have been using for reference.
When I try socket.on('connect', console.log(socket.connected)) on the client side it always returns false and when I log the connect_error it returns server error with the following traceback:
Error: server error
at Socket.onPacket (socket.js:317:1)
at XHR.push../node_modules/#socket.io/component-emitter/index.js.Emitter.emit (index.js:143:1)
at XHR.onPacket (transport.js:100:1)
at callback (polling.js:83:1)
at Array.forEach (<anonymous>)
at XHR.onData (polling.js:86:1)
at Request.push../node_modules/#socket.io/component-emitter/index.js.Emitter.emit (index.js:143:1)
at Request.onData (polling-xhr.js:188:1)
at Request.onLoad (polling-xhr.js:229:1)
at XMLHttpRequest.xhr.onreadystatechange (polling-xhr.js:147:1)
These are the relevant parts of my index.js server file on the backend:
const express = require('express');
const cors = require('cors');
const app = express();
// /db/session is express-session related code
const session = require('./db/session');
const { createServer } = require('http');
const { Server } = require('socket.io');
const PORT = process.env.PORT || 5000;
const httpServer = createServer(app);
app.use(cors({
// DEV_ORIGIN is http://localhost:3000
origin: process.env.DEV_ORIGIN,
credentials: true,
}));
const io = new Server(httpServer, {
cors: {
origin: process.env.DEV_ORIGIN,
methods: ["GET", "POST"],
credentials: true
}
});
app.use(session);
io.use((socket, next) => {
session(socket.request, {}, next);
});
httpServer.listen(PORT, () => console.log(`Server running on port ${PORT}`));
// this never seems to do anything
io.on('connection', function() {
console.log('Connected')
});
Here is the main file I have on the client side for the Socket.io connection:
import io from 'socket.io-client';
// API_ORIGIN is http://localhost:5000
export let socket = io(process.env.API_ORIGIN, {
withCredentials: true,
autoConnect: true,
});
I am testing using the socket from this file in a component like so:
import { socket } from '../../services/socket.js';
import React, { useEffect } from 'react';
export default function Lobby() {
useEffect(() => {
socket.on('connect',
console.log(socket.connected)
)
socket.on('connect_error', (err) => {
console.log(err)
});
}, [])
}
But as I mentioned above, socket.connected always returns false. I would really appreciate your help!

I managed to resolve it. The issue was caused by process.env.API_ORIGIN. By changing the code as follows, I was able to get it to work.
The new client side socket.io file:
import { io } from "socket.io-client";
import { serverAddress } from "../settings";
export let socket = io(serverAddress, {
withCredentials: true,
autoConnect: true,
});
and the settings file I created:
const LOCAL_ADDRESS = 'http://localhost:5000';
const PRODUCTION_ADDRESS = [PRODUCTION URL HERE]
export const devEnv = process.env.REACT_APP_ENV === 'development';
export const serverAddress = devEnv? LOCAL_ADDRESS : PRODUCTION_ADDRESS;

Related

WebSocket connection to 'ws://localhost:8000/socket.io/?EIO=4&transport=websocket' failed:

This is a simple chat application project with Socket.io, but i am having problem connecting socket.io client which is in React to my server in Node
Connection code for my server is like this
const server = http.createServer(app)
const io = socketio(server, {
cors: {
origin: 'http://localhost:3000',
methods: ['GET', 'POST'],
}
})
const onSocketConnection = socket => {
console.log('Socket connected')
socketConnection(io, socket, db)
}
io.on("connection", onSocketConnection)
Connection in client side is like this
import io from "socket.io-client"
const socket = io.connect('http://localhost:8000',{
cors: {
origin: "http://localhost:5000",
credentials: true
},transports : ['websocket']
})
This is the error i am reviving
WebSocket connection to 'ws://localhost:8000/socket.io/?EIO=4&transport=websocket' failed:
Error snapshot
server side (http://localhost:8000):
import { Server } from 'socket.io';
...
const server = http.createServer(app)
const io = new Server(server, {
cors: {
origin: ['http://localhost:3000'],
}
})
// listening for connections from clients
io.on('connection', (socket) =>{
// listening to events from client
socket.on('eventName', (params, callback) => {
...
// send data back to client by using ack callback
callback(data)
// send data back to client by using emit
socket.emit('eventName', data)
// broadcasting data to all other connected clients
socket.broadcast.emit('eventName', data)
})
})
client side (http://localhost:3000):
import { io } from "socket.io-client"
const socket = io('http://localhost:8000',{
withCredentials: true
})
// emit:
socket.emit('eventName', params, callback => {
...
})
// listen to events from sever:
socket.on('eventName', callback => {
...
})

react client: websocket.js:83 WebSocket connection to 'ws://localhost:3009/socket.io/?EIO=4&transport=websocket' failed:

i have a node backend using socket io
first in app.js initialize te app
const express = require("express")
const app = express()
module.exports = {
app,
express
}
then in io.js, i create the socket server
const { app } = require("./app");
const http = require("http");
const socketio = require("socket.io");
const server = http.createServer(app);
const io = socketio(server);
module.exports = io;
then in the server.js first i import the app.js for api calls then i import io.js
require("dotenv").config();
const { app, express } = require("./app");
const logger = require("./logger");
const io = require("./io");
then i simply add emit listen code in the server.js
io.on("connection", (socket) => {
console.log("we have a new connection");
socket.on("disconnect", () => {
console.log("the socket disconnected");
});
socket.on("join", ({ user_id }, callback) => {
// const notification = getListNotifications(user_id);
// const popup = getUserPopup(user_id);
// socket.emit("nofication", { popup: popup.count, notification });
socket.emit("nofication", { popup: 3, notificaton: { a: 1 } });
socket.join(user.room);
callback();
});
then i run the server.js file in dev mode nodemon server.js
Then in react i simply use socket.io
import io from "socket.io-client";
useEffect(() => {
socket = io("ws://localhost:3009", {
"force new connection": true,
reconnectionAttempts: "Infinity",
timeout: 10000,
transports: ["websocket"],
});
return () => {
socket.disconnect();
};
}, []);
it gives me this error in browser console
the server node.js console is receiving https protocol
i find out in other answers that it maybe some protocol issue.
happy to learn from you. Thanks in advance
Happened to me that i was listening the server with app.listen which only recieves https protocol....but i have created a seperated ws server with the server variable which should listen to a port so that the server can receive ws connection...
better to use this library npm link will make work much easier...

socket.io wont connect after reload when communicating with react socket.io-client

I am trying to create simple socket.io server/client
this error appears to happen when I send http request to the server
First I created html file to act as client and everything was working fine
When I started using Socket inside my React app server went nuts !
First time I start the server everything is fine and socket is working
but when I refresh the page I can't connect to server from anywhere anymore
Server code ...
const express = require('express');
class Server {
constructor({ config, router, logger }) {
this.config = config;
this.logger = logger;
this.express = express();
this.express.disable('x-powered-by');
this.express.use(router);
}
startSocket(server) {
console.log('initing');
const io = require('socket.io')(server, {
cors: {
origin: '*',
methods: ['GET', 'POST'],
},
});
io.on('connection', (socket) => {
console.log('connected ' + socket.id);
});
}
start() {
return new Promise((resolve) => {
const http = this.express.listen(this.config.web.port || 6066, () => {
const { port } = http.address();
this.logger.info(`[p ${process.pid}] Listening at port ${port}`);
resolve();
});
this.startSocket(http);
});
}
}
module.exports = Server;
React code
import { io } from 'socket.io-client';
export class Socket {
constructor() {
this.socket = io('http://localhost:4000', {
rejectUnauthorized: false,
});
this.binds();
}
binds() {
this.socket.on('connect', () => {
console.log(this.socket.id);
});
this.socket.on('bong', (msg) => {
console.log(msg);
});
}
bing() {
this.socket.emit('bing', { msg: 'test' });
}
}
export default new Socket();
turns out 'socket.io' conflicts with 'express-status-monitor' which caused this problem

React and Express - Error during WebSocket handshake on localhost

I'm having trouble setting up a WebSocket connection using socket.io on my localhost. I'm using express on the server side and React on the client side.
I get the following message whenever I try to open a connection:
WebSocket connection to 'ws://localhost:5000/socket.io/?EIO=4&transport=websocket' failed: Error during WebSocket handshake: Unexpected response code: 404
I've seen some people having similar issues related to nginx or other web servers, but my problem is happening on localhost, which is why I am asking this question
Server-side code (I am using modules for the import, and I would like to keep it that way)
import express from 'express';
import bodyParser from 'body-parser';
import cors from 'cors';
import { createServer } from 'http';
import * as socketio from 'socket.io';
const app = express();
app.use(bodyParser.json({ limit: '30mb', extended: true }));
app.use(bodyParser.urlencoded({ limit: '30mb', extended: true }));
app.use(cors());
app.use('/foo', bar);
const server = createServer(app)
const io = new socketio.Server(server);
io.on('connect', socket => {...});
const PORT = process.env.PORT || 5000
app.listen(PORT, () => console.log(`Server running on port ${PORT}`)))
Client-side code (I've already tried passing different values to the "transports" array but it did not help) :
import io from 'socket.io-client';
let socket;
const Component = () => {
...
const { id } = useParams();
const ENDPOINT = 'ws://localhost:5000';
useEffect(() => {
socket = io(ENDPOINT, { transports: ['websocket', 'polling', 'flashsocket'] });
return () => {
socket.emit('disconnect');
socket.off();
}
}, [ENDPOINT, id]);
return (...)
})
Change last line of Server side code to
server.listen(PORT, () => console.log(`Server running on port ${PORT}`));

Problems connecting to my NodeJs server socket and typescript

I've tried everything and I can't afford to waste any more time please need help, I've been trying to run the code in this post:https://medium.com/#mogold/nodejs-socket-io-express-multiple-modules-13f9f7daed4c,I've been trying to run the code in this post, I liked it a lot because as I see it fits very well with big projects, the problem arises when I want to connect to it, throws the following errors at me: console: I already try setting up the headers of my application and I've tried codes that I read from similar problems but none ah worked, I leave you the condigo of my server.ts, socket.ts, job.ts and routes.ts, I hope you can help me please :c
server.ts
import express from "express";
const http = require("http");
import { router} from './routes/routes';
import bodyParser from "body-parser";
import morgan from "morgan";
import { PORT} from "./core/utils/config"
import errorMiddleware from './core/middleware/error.middleware';
import socket from "./socket";
const app = express();
const server = http.createServer(app);
app.use(bodyParser.json());
app.use(router);
app.use(morgan("dev"));
app.use(errorMiddleware);
app.listen(3000, ()=> console.log("[SERVER] list is running in port http://localhost:"+PORT));
socket.connect(server);
socket.ts
let connection: any = null;
export class Socket {
socket: any;
constructor() {
this.socket = null;
}
connect(server: any) {
const io = require("socket.io").listen(server);
io.on("connection", (socket: any) => {
this.socket = socket;
});
}
emit(event: any, data: any) {
this.socket.emit(event, data);
}
static init(server: any) {
if (!connection) {
connection = new Socket();
connection.connect(server);
}
}
static getConnection() {
if (connection) {
return connection;
}
}
}
export default {
connect: Socket.init,
connection: Socket.getConnection
}
job.ts
import socket from "../../../socket";
export class JobSockets {
emitUpdate() {
const connection = socket.connection();
if (connection) {
connection.emit("jobs", {
hola: "hola desde mi backend"
});
}
}
}
routes.ts
import express from "express";
import indexAppointment from "../features/Appointment/routes/index";
import indexUser from "../features/User/routes/index";
import cors from "cors";
const router = express.Router();
const options: cors.CorsOptions = {
allowedHeaders: [
'Origin',
'X-Requested-With',
'Content-Type',
'Accept',
'X-Access-Token',
],
credentials: true,
methods: 'GET,HEAD,OPTIONS,PUT,PATCH,POST,DELETE',
origin: "*",
preflightContinue: false,
};
router.use(cors(options));
router.options('*', cors(options));
router.use(indexAppointment);
router.use(indexUser);
export {
router
};
client index.html
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js"></script>
</head>
<body>
<p>Check the console to see the messages coming through</p>
<script>
let socket;
window.onload = () => {
socket = io.connect("http://192.168.1.7:3000");
socket.on("jobs", (msg) => {
console.log(msg)
})
};
</script>
</body>
</html>
import indexAppointment from "../features/Appointment/routes/index";
import expres from "express"
import getAppointment from "./getAppointment/getAppointment";
import createAppoinment from "./createAppointment/create_appointment";
import updateAppoinment from "./updateAppointment/update_appointment";
import deleteAppoinment from "./deleteAppointment/delete_appointment";
const router = expres.Router();
router.use("/appointment",getAppointment);
router.use("/appointment",createAppoinment);
router.use("/appointment",updateAppoinment);
router.use("/appointment",deleteAppoinment);
export default router;
import indexUser from "../features/User/routes/index";
import expres from "express"
import createUser from "./createUser/create_user";
import deleteUser from "./deleteUser/delete_user";
import updateUser from "./updateUser/update_user";
import getUsers from "./getUser/get_user";
import createUserInfoAppointment from "./createUserInfoAppointment/create_user_info_appointment";
import getUserInfoAppointments from "./getuserinfoappointment/get_user_info_appointment";
const router = expres.Router();
router.use("/user",createUser);
router.use("/user",deleteUser);
router.use("/user",updateUser);
router.use("/user",getUsers);
//managment use case
router.use("/user",createUserInfoAppointment);
router.use("/user",getUserInfoAppointments);
export default router;
By default front end socket.io will connect to path /socket.io at the url provided. In your case it is localhost:3000. It doesn't seem like you have any routes re-defining this endpoint which is good.
The issue appears to be how the server is being started. You want http to be the listener here rather than the express app. So do the following,
Remove this part
app.listen(3000, ()=> console.log("[SERVER] list is running in port http://localhost:"+PORT));
And add this instead
app.set( "ipaddr", "127.0.0.1" ); --> May be omitted since you're using a different ip. This way it lets app use the ip that it finds. So try it without first and see if that works. If not, then change to your ip.
app.set( "port", 3000 );
server.listen(3000, () => {
console.log('server is running on port', server.address().port);
});

Resources