React client receives two connections using Socket.io - node.js

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.

Related

Flutter Socket io disconnects after some seconds

Am using a local socket server using express which is expose to the internet using ngrok. This is the server code:
const app = require('express')();
const http = require('http').createServer(app);
app.get('/', (req, res) => {
res.send("Node Server is running. Yay!!");
});
//Socket Logic
const socketio = require('socket.io')(http)
socketio.on("connection", (userSocket) => {
console.log('Connected to socket');
});
http.listen(3000, () => {
console.log('listening on port 3000');
});
and my connection logic is:
void connectToServer() {
try {
socket = io('https://fa6387728fcd.ngrok.io', <String, dynamic>{
'transports': ['websocket'],
'autoConnect': false,
});
// Connect to websocket
socket.connect();
// Handle socket events
socket.on('connect', (data) => print('Connected to socket server'));
socket.on('disconnect', (reason) => print('disconnected $reason'));
socket.on('error', (err) => print('Error: $err'));
} catch (e) {
print(e.toString());
}
}
But i keep getting disconnected ping timeout or sometimes i get disconnected transport close
I had the same problem.
The problem wasn't caused by the socket_io_client package.
When i update socket.io on my server side, the problem is solved.
Just run npm install socket.io#latest command on your node.js server.
According to the socket_io_client official doc, use this workaround if you are using https server:
class MyHttpOverrides extends HttpOverrides {
#override
HttpClient createHttpClient(SecurityContext context) {
return super.createHttpClient(context)
..badCertificateCallback =
(X509Certificate cert, String host, int port) => true;
}
}
void main() {
HttpOverrides.global = new MyHttpOverrides();
runApp(MaterialApp(
...
));
}

io.sockets.emit() won't work in production

I am trying to setup a socket in production like so:
client :
import openSocket from 'socket.io-client';
function handleSomething() {
let socketServer = 'https://staging.app.xxx.eu:9999';
const socket = openSocket(socketServer);
socket.on('calendlyHook', () => {
console.log("*** HERE");
...
socket.emit('closeSocket');
socket.close();
socket.removeAllListeners();
});
}
server :
const app = require('express')();
const http = require('http').createServer(app);
const io = require('socket.io')(http);
function openSocket() {
io.close();
io.set('origins', '*:*');
io.on('connection', (client) => {
console.log('Socket connected');
client.on('closeSocket', () => {
io.close();
io.removeAllListeners();
console.log('Socket closed');
});
});
const port = 9999;
io.listen(port);
console.log('*** listening on port ', port);
}
Then server-side, another function tries the following:
io.emit('calendlyHook');
or
io.sockets.emit('calendlyHook');
I have several issues in production (none of which happen on localhost):
console.log('*** listening on port ', port) is working fine
console.log('Socket connected') is not happening
io.emit('calendlyHook') or io.sockets.emit('calendlyHook') are not doing anything
I do not have any web server proxy set up on that url.
What is wrong here? Thanks!

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

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]);

Unable to connect to socket IO locally in reactjs?

I am using nodeJs as backend and reactJs as my frontend the thing is I emitted a socket emit function from node
var server = require('http').createServer();
var io = require('socket.io')(server);
io.emit('quantity_check', 'KR')
now the issue is I'm unable to catch the emit
let serverUrl = 'localhost:3008'
const socket = socketIOClient(serverUrl);
socket.on("quantity_check", data => this.setState({ kiiii: data }));`
const socket = socketIOClient(serverUrl);
I'm checking this locally even i tried with my ip its not connecting I am not sure where the issue occurs
pc:nodejs and reactjs running on different ports
Can you post the code of you node server file and the react file where are you are listening to the sockets?. Anyway i hope that emit event is inside the connection
io.on('connection', function(socket) {
io.emit('quantity_check', 'KR')
}
and did you use the life cycle method componentDidMount to receive message
componentDidMount() {
socket.on("quantity_check", data => {
console.log(data);
});
}
Try something like this.
server
const server = require('http').createServer();
const io = require('socket.io')(server);
io.on('connect', (socket) => {
io.emit('quantity_check', 'KR');
});
Client(React side)
import io from 'socket.io-client';
const socket = io('http://localhost:3008');
export class App extends Component {
componentDidMount() {
socket.on('connect', () => {
console.log(socket.connected);
});
socket.on("quantity_checke", data => {
console.log(data);
});
}
render().......
}

Nodejs Socket.io Express failed to handshake after calling HTTP API

I am using SocketIo with Nodejs, Express server and MongoDB, I followed the documentation . it works fine when connecting multiple clients they can send messages to each other without any problem . when I made an Http request, I cannot connect any new clients and get this error.
socket.io.js:7370 WebSocket connection to
'ws://localhost:28232/socket.io/?userId=userAmr&EIO=3&transport=websocket&sid=wNTTgrUD-PSeNaIcAAAF'
failed: Error during WebSocket handshake: Unexpected response code:
400
the other connected users before the Http request can continue sending messages without any problem.
I debugged the Socket library and found the client socket request go to connect function then fire errorCode:1
This this my code
/**
* Create Express server.
*/
const app = express();
// API endpoint
app.get('/api/test',(req,res)=>{
res.status(200).send({test:"test"});
});
/**
* Init socket
*/
// the following line not working too
// const server = require('http').createServer(app);
const server = require('http').Server(app);
const io = require('socket.io')(server);
io.on('connection', (socket) => {
// emit message to group
socket.on('emitMessage', (data) => {
io.emit('emitMessage', data);
});
});
The Client side code
import { Injectable } from '#angular/core';
import * as io from "socket.io-client/dist/socket.io.js"
import { BehaviorSubject } from 'rxjs';
#Injectable()
export class AppSocketService {
private url = 'http://localhost:28232';
private socket;
constructor() {
}
connect(){
this.socket = io(this.url,{
query:{userid:"123"},
forceNew:true,
'force new connection': true,
autoConnect: true,
reconnectionDelay: 1000,
timeout: 100000,
reconnectionDelayMax: 5000,});
this.socket.on('connect', () => {
console.log("connect",{"socketId":this.socket.id});
this.startListening();
});
}
startListening(){
this.socket.on('emitMessage', (data) => {
console.log(data);
});
}
emitMessage(message){
this.socket.emit('emitMessage', {message});
}
}
Client version:"socket.io-client": "^1.7.3"
Server version: "socket.io": "^1.7.3"
i found the problem, the package express-status-monitor making this wrong behavior .
try to remove it, and it will work perfectly
// comment these lines, as they making the issue
// const expressStatusMonitor = require('express-status-monitor');
// app.use(expressStatusMonitor());
The final code:
let app = require('express')();
// these two lines were making the problem, please comment them. if you want to reproduce the problem enable them again
// const expressStatusMonitor = require('express-status-monitor');
// app.use(expressStatusMonitor());
let http = require('http').Server(app);
let io = require('socket.io')(http);
let port = process.env.PORT || 3000;
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
app.get('/api/v0/availabilities',(req,res)=>{
res.status(200).send({test:"test"});
});
io.on('connection', (socket) => {
// emit message to group
socket.on('emitMessage', (data) => {
io.emit('emitMessage', data);
});
});
http.listen(port, function(){
console.log('listening on *:' + port);
});

Resources