Socket.io v3.0.4 not connecting, v2.3 does work - node.js

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.

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

Expo react-native will not connect to socketio(Android and iOS)

im trying to connect to socketio with expo and reacti-native for ios(connection through expo app tunnel connection) and android with emulator, when i tried to connect with these the socket won't connect but if i open the expo app in broswer socket connection works but on mobile emulators not.. what can i do?
code for client
import { StatusBar } from 'expo-status-bar';
import React, { useEffect, useState } from 'react';
const io = require('socket.io-client');
import { SafeAreaProvider, SafeAreaView } from 'react-native-safe-area-context';
import useCachedResources from './hooks/useCachedResources';
import Navigation from './navigation';
import { Provider } from 'react-redux';
import { store } from './redux/store'
export default function App() {
const isLoadingComplete = useCachedResources();
const [data, setData] = useState(null)
useEffect(() => {
const socket = io('http://localhost:5000', {
});
socket.on("ping", (data: any) => {
setData(data)
})
}, [])
console.log(data)
if (!isLoadingComplete) {
return null;
} else {
return (
<Provider store={store}>
<SafeAreaProvider>
<StatusBar style="dark" />
<Navigation />
</SafeAreaProvider>
</Provider>
);
}
}
code for server
require("dotenv").config();
const express = require("express");
const http = require("http");
const socketIO = require('socket.io');
const app = express();
const server = http.createServer(app);
const PORT = process.env.PORT || 5000;
const io = socketIO(server);
io.on('connection', socket => {
console.log('client connected on websocket');
setInterval(() => {
io.emit('ping', { data: (new Date()) / 1 });
}, 1000);
});
server.listen(PORT, () => console.log(`Server Running on Port: http://localhost:${PORT}`));
Make sure you are connecting with the right versions in each part, client and server.
Review https://socket.io/docs/v3/client-installation/index.html to make sure you have the right versions. I went through the source code and make sure mine was setup right and couldn't figure out why it wouldn't run.
I had a 4.0.1 of the socket.io-client installed in my react native expo app but only had 2.1.1 socket.io installed in the server. Once I upgraded to 4 on the server everything worked.
Also on the client side change
const socket = io('http://localhost:5000', {});
to
const socket = io('http://localhost:5000', {transports: ['websocket']});

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...

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

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