I’m building a chat application in React js and Node js. The events that I have written in React.js and Node.js do not seem to be triggered. I can login and see data in both the browser and the console, but as soon as I installed Socket.IO for the client and server, not only did I get issues from Socket.IO on the client side, none of the events are being triggered.
socketConnect.js in the client side
import { useEffect } from "react";
import socketIOClient from "socket.io-client"
function useSocket (user, dispatch) {
useEffect(() => {
const socket = socketIOClient.connect("http://127.0.0.1:3000")
socket.emit("join", user)
socket.on("typing", (user) => {
console.log("Event", user)
})
socket.on("friends", (friends) => {
console.log("Friends", friends)
})
socket.on("online", (user) => {
console.log("Online", user)
})
socket.on("offline", (user) => {
console.log("Offline", user)
})
}, [dispatch])
}
export default useSocket
/socket/index.js in the server side
const socketIo = require("socket.io");
const { sequelize } = require("../models");
const users = new Map();
const userSockets = new Map();
const SocketServer = (server) => {
const io = socketIo(server)
io.on("connection", (socket) => {
socket.on("join", async (user) => {
let sockets = [];
if (user.has(user.id)){
const existingUser = users.get(user.id)
existingUser.sockets = [...existingUser.sockets, ... [socket.id]]
users.set(user.id, existingUser);
sockets = [...existingUser.sockets, ... [socket.id]]
userSockets.set(socket.id, user.id)
} else {
users.set(user.id, {id: user.id, sockets: [socket.id]})
sockets.push(socket.id);
userSockets.set(socket.id, user.id)
}
const onlineFriends = [];
const chatters = getChatters(user.id)
console.log(chatters);
for (let i = 0; i < chatters.length; i++){
if (users.has(chatters[i])){
const chatter = users.get(chatters[i])
chatter.sockets.forEach(socket => {
try {
io.to(socket).emit("online",user);
} catch (error) {
}
})
onlineFriends.push(chatter.id)
}
}
sockets.forEach(socket => {
try {
io.to(socket).emit("friends", onlineFriends)
} catch (error) {
}
})
console.log("New User Joined: ", user.firstName);
io.to(socket.id).emit("typing", "User typing...")
})
socket.on("disconnect", async () => {
if (userSockets.has(socket.id)){
const user = users.get(userSockets.get(socket.id))
if (user.sockets.length > 1) {
user.sockets = user.sockets.filter(sock => {
if (sock !== socket.id) return true
userSockets.delete(sock)
return false
})
users.set(user.id, user)
} else {
const chatters = await getChatters(user.id)
for (let i = 0; i < chatters.length; i++){
if (users.has(chatters[i])){
users.get(chatters[i]).sockets.forEach(socket => {
try {
io.to(socket).emit("offline",user);
} catch (error) {
}
})
}
}
userSockets.delete(socket.id);
users.delete(user.id)
}
}
});
})
}
const getChatters = async (userId) => {
try {
const [results, metadata] = await sequelize.query(`
select "cu"."userId" from "ChatUsers" as cu
inner join (
select "c"."id" from "Chats" as c
where exists (
select "u"."id" from "Users" as u
inner join "ChatUsers" on u.id = "ChatUsers"."userId"
where u.id = ${parseInt(userId)} and c.id = "ChatUsers"."chatId"
)
) as cjoin on cjoin.id = "cu"."chatId"
where "cu"."userId" != ${parseInt(userId)}
`)
return results.length > 0 ? results.map(el => el.userId) : []
} catch (e) {
console.log(e);
return []
}
}
module.exports = SocketServer
root index.js in the server side
const express = require("express");
const config = require('./config/app')
const router = require('./router');
const bodyParser = require('body-parser');
const cors = require('cors');
const app = express();
const http = require("http");
const socketIo = require("socket.io")
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
app.use(cors());
app.use(router);
app.use(express.static(__dirname + "/public"));
app.use(express.static(__dirname + "/uploads"));
const port = config.appPort;
const server = http.createServer(app);
const SocketServer = require("./socket")
const io = socketIo(server);
SocketServer(server);
io.on("connection", (socket) => {
console.log("New client connected: ", socket.id);
socket.on("join", (user) => {
console.log("New user joined: ", user);
io.to(socket.id).emit("typing", "User typing...");
});
socket.on("disconnect", () => {
console.log("Client disconnected: ", socket.id);
});
});
server.listen(port, () => {
console.log(`Server is running on port ${port}`)
});
Chat.js which renders the components
import React, { useEffect } from 'react'
import { useSelector, useDispatch } from 'react-redux'
import useSocket from './hooks/socketConnect'
import Navbar from './components/Navbar/Navbar'
import { fetchChats } from '../../store/actions/chat'
import FriendList from './components/FriendList/FriendList'
import Messenger from './components/Messenger/Messenger'
import './Chat.scss'
const Chat = () => {
const dispatch = useDispatch()
const user = useSelector(state => state.authReducer.user)
useSocket(user, dispatch)
useEffect(() => {
dispatch(fetchChats()).then(res => console.log(res)).catch(err => console.log(err))
}, [dispatch])
return (
<div id='chat-container'>
<Navbar />
<div id='chat-wrap'>
<FriendList />
<Messenger />
</div>
</div>
);
}
export default Chat```
I have multiple users in the database. When a user logs in and is online, another user from the database, if logged in, will be notified from the console, but none of the events are being triggered.