SocketIO-Client and NodeJS - Connecting but nothing from emit/on - node.js

I'm getting a successful "A user has appeared!" connection message on the back-end. Be there seems to be no communication after the connect event.
Also, the front end keeps disconnecting and reconnecting. Is this bad?
Super socket-io novice here, just started learning tonight.
Thank you in advance for the help.
Node.JS/Express Backend:
const express = require('express')
const server = express();
const http = require('http').createServer(server);
const socketio = require('socket.io');
// ! Express --
server.use(require('cors')());
server.use(express.json());
server.get("/", (req, res) => {
res.status(200).json({
message: `You've hit the socket.io backend!`
})
})
// ! SocketIO
const io = socketio(http);
io.on('connect', socket => {
// ! Emit CheatSheet -> https://socket.io/docs/emit-cheatsheet/
// -> I believe `socket` referes to the open instance of a connection.
// -> This allows us to use functions such as:
// -> .on(eventName, cb(data)) | Use `on` when you are getting data FROM the front end.
// -> .emit(eventName, { data }) | Use `emit` when you are sending data TO the front end.
console.log(`A user has appeared!`)
socket.on("hello", data => console.log(data))
socket.on('disconnect', () => {
console.log(`A user has disappeared.`)
})
});
const PORT = process.env.PORT || 5000;
http.listen(PORT, () => console.log(`Server started on ${PORT}.`));
React Front-End (App.js):
import React, { useEffect, useState } from 'react'
// -> SocketIO
import io from 'socket.io-client';
let socket;
export default () => {
const ENDPOINT = process.env.ENDPOINT || 'http://--server-ip--/'
const [message, setMessage] = useState('Secret Message from the Front-End')
useEffect(() => {
socket = io(ENDPOINT, {
transports: ['websocket']
});
socket.emit('hello', "Hello from the front-end!")
}, [ENDPOINT]);
return (
<div>
<p>{ message }</p>
</div>
)
}

In your client you must wait to the connection be established using the appropriate events before emitting something
useEffect(() => {
socket = io(ENDPOINT, {
transports: ['websocket']
});
socket.on('connect', function(){
socket.emit('hello', "Hello from the front-end!")
});
}, [ENDPOINT]);

Related

React JS socket.io-client opens multiple connections

I have a simple React JS app connected to a socket io server. Whenever I open the app in the browser, the client sends new connection request to the server every 5 seconds.
server:
const express = require('express');
const app = express();
const http = require('http');
const server = http.createServer(app);
const io = require('socket.io')(server);
io.on('connection', (socket) => {
console.log('socket id:', socket.id);
})
server.listen(3001, () => {
console.log('Listening on port 3001');
})
client:
import React from 'react';
import io from 'socket.io-client';
const socket = io('http://localhost:3001');
const App = () => {
return (
<div>Hi there!</div>
);
}
export default App;
logs on the server:
socket id: ByXQEMgeVaQ5AGw1AAAA
socket id: 8LzNQsyeYq7GSEvqAAAB
socket id: bbuYEs4kKzjxXuBsAAAC
socket id: vwprv4hnJbRlStG4AAAD
I suspect there could be something wrong on my laptop, cause I don't see anything wrong in the code, any ideas?
Thanks in advance
I would recommend calling connect inside a useEffect and return the disconnect method to be called when the component dismounts.
const [socket, setSocket] = useState(null)
useEffect(() => {
const newSocket = io('http://localhost:3001')
setSocket(newSocket)
return socket.disconnect()
}, [])
Can you try to wrap the client side socket creation in a useEffect that only runs once? I'm curious to see if the behavior still appears.
import React from 'react';
import io from 'socket.io-client';
const socket = io('http://localhost:3001');
const App = () => {
useEffect(() => {
const socket = io('http://localhost:3001');
}, [])
return (
<div>Hi there!</div>
);
}
export default App;
Actually I just found the root cause, I had a mismatch between my client version and my server version. I updated the client version to v4 and now it is working

React client receives two connections using Socket.io

I am developing a simple app with SocketIO and I am encountering this problem. In the server I have the following code:
const httpServer = require('http').createServer();
const socketIO = require('socket.io');
const port = process.env.PORT_WS || 5001;
const io = socketIO(httpServer, { cors: { origin: '*' } });
io.on('connection', (socket) => {
console.log('Connected to socket');
socket.on('join-room', () => {
console.log('joined room')
});
});
httpServer.listen(port, () => {
console.log(`Listening on the port ${port}`);
});
In the client I have the following code:
import { io } from 'socket.io-client';
export default class SocketConnection {
constructor() {
this.initializeSocketConnection();
this.initializeSocketEvents();
}
initializeSocketConnection() {
console.log('I am here');
this.socket = io('ws://localhost:5001');
}
initializeSocketEvents() {
this.socket.on('connect', () => {
console.log('Socket connected');
});
}
}
I get in the console two Socket connected messages.
This is not a re-render issue because the I am here message is logged only once.
I am using socket.io version 4.0.1 both in the client and in the backend.
So this is happening because, in React Strict Mode, constructors are called two times. React seems to hide this. As the console.log('Socket connected'); is inside an "on" event, React has no way to "hide" this. Thus, 'I am here' is going to be shown once but 'Socket connected' is going to be shown twice.

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 v3.0.4 not connecting, v2.3 does work

Summary
I have basic sample code which works in socket.io 2.3 which does not work in socket.io 3.0, I want to understand what I need to change.
Full Description
I have a node.js / react project and I wanted to use socket.io. To do this, I implemented the example code from this article, using socket.io v3.0.4, which follows.
Server side:
const http = require("http");
const socketIo = require("socket.io");
const port = process.env.PORT || 4001;
const index = require("./routes/index");
const app = express();
app.use(index);
const server = http.createServer(app);
const io = socketIo(server);
let interval;
io.on("connection", (socket) => {
console.log("New client connected");
if (interval) {
clearInterval(interval);
}
interval = setInterval(() => getApiAndEmit(socket), 1000);
socket.on("disconnect", () => {
console.log("Client disconnected");
clearInterval(interval);
});
});
const getApiAndEmit = socket => {
const response = new Date();
// Emitting a new message. Will be consumed by the client
socket.emit("FromAPI", response);
};
server.listen(port, () => console.log(`Listening on port ${port}`));
Client Side:
import React, { useState, useEffect } from "react";
import socketIOClient from "socket.io-client";
const ENDPOINT = "http://127.0.0.1:4001";
function App() {
const [response, setResponse] = useState("");
useEffect(() => {
const socket = socketIOClient(ENDPOINT);
socket.on("FromAPI", data => {
setResponse(data);
});
}, []);
return (
<p>
It's <time dateTime={response}>{response}</time>
</p>
);
}
export default App;
on the server, I was receiving the error
socket.io:client client close with reason ping timeout
which led me to this article, which implied a version issue.
Based on that, I've attempted a few things, but specifically, I was running socket.io and socket.io-client both version 3.0.4. I uninstalled and reinstalled v 2.3.0/2.3.1. It now works flawlessly.
So my question is: what do I need to change to make this work with the more recent version of socket.io.

Socket.io Node - React connection false

I'm not able to connect to socket on client for some reason. Logging socket all the time returns False. I tried official Socket.io app and it is working fine.. Can anyone help and let me know what I'm missing here?
Server
const app = require('express')()
const http = require('http').Server(app)
const io = require('socket.io')()
const router = require('./router')
const PORT = process.env.PORT || 8080
io.on('connection', (socket) => {
console.log('user connected');
socket.on('disconnect', () => {
console.log('user disconnected');
})
})
app.use(router)
app.listen(PORT, () => {console.log(`Server running on port ${PORT}`)})
Client
import queryString from 'query-string'
import io from 'socket.io-client'
let socket;
const Chat = () => {
const ENDPOINT = 'http://localhost:8080'
useEffect(() => {
socket = io(ENDPOINT)
console.log(socket);
})
return (
<div>
Chat
</div>
)
}
export default Chat
Solution
Server is listening on app instead http.listen(...)
You should pass http into socket.io:
const io = require('socket.io')(http);
Try using your ip address instead of the localhost

Resources