diff --git a/back/api/channels.js b/back/api/channels.js index a504296..ba88722 100644 --- a/back/api/channels.js +++ b/back/api/channels.js @@ -11,16 +11,6 @@ router.get('/', async (req, res) => { res.send(channels); }); -const sockets = new Set(); - -router.ws('/', function(ws, req) { - sockets.add(ws); - - ws.on('close', () => { - sockets.delete(ws); - }); -}); - router.get('/:name', async (req, res) => { const name = req.params.name; const connection = await getConnection(); @@ -33,22 +23,6 @@ router.get('/:name', async (req, res) => { } }); -const channelSockets = new Map(); - -router.ws('/:name', function(ws, req) { - const name = req.params.name; - - if (!channelSockets.has(name)) { - channelSockets.set(name, new Set()); - } - - channelSockets.get(name).add(ws); - - ws.on('close', () => { - channelSockets.get(name).delete(ws); - }); -}); - router.get('/:name/messages', async (req, res) => { const name = req.params.name; const connection = await getConnection(); @@ -105,21 +79,11 @@ router.post('/:name/messages/send', async (req, res) => { connection.end(); - if (sockets.size > 0) { - for (const client of sockets) { - if (client.readyState === 1) { - client.send('new_message'); - } - } - } - - if (channelSockets.has(name)) { - for (const client of channelSockets.get(name)) { - if (client.readyState === 1) { - client.send('new_message'); - } - } - } + req.sockets.emit({ + type: 'new_message', + channel_id: channel[0].id, + user_id: user.id, + }); res.send({ message: 'Message sent' }); }); @@ -157,21 +121,11 @@ router.post('/:name/messages/delete', async (req, res) => { await deleMentions(connection, message_id); connection.end(); - if (sockets.size > 0) { - for (const client of sockets) { - if (client.readyState === 1) { - client.send('delete_message'); - } - } - } - - if (channelSockets.has(name)) { - for (const client of channelSockets.get(name)) { - if (client.readyState === 1) { - client.send('delete_message'); - } - } - } + req.sockets.emit({ + type: 'delete_message', + channel_id: channel[0].id, + user_id: user.id, + }); res.send({ message: 'Message deleted' }); }); @@ -201,13 +155,9 @@ router.post('/add', async (req, res) => { await addChannel(connection, name, description, user.id); connection.end(); - if (sockets.size > 0) { - for (const client of sockets) { - if (client.readyState === 1) { - client.send('new_channel'); - } - } - } + req.sockets.emit({ + type: 'new_channel' + }); res.send({ message: 'Channel added' }); }); diff --git a/back/index.js b/back/index.js index aefd4a6..437dc15 100644 --- a/back/index.js +++ b/back/index.js @@ -14,6 +14,10 @@ app.use(express.json()); app.use(cookieParser()); app.use(cors()); +const { router, socketsMiddleware } = require("./libs/middlewares"); +app.use("/api/ws", router); +app.use(socketsMiddleware); + function loadRoutes(folderName) { const routesPath = path.join(__dirname, folderName); const files = fs.readdirSync(routesPath); diff --git a/back/libs/middlewares.js b/back/libs/middlewares.js index 6673e21..ebb53ee 100644 --- a/back/libs/middlewares.js +++ b/back/libs/middlewares.js @@ -1,5 +1,6 @@ const jwt = require('jsonwebtoken'); const { getConnection, getUser } = require('./mysql'); +const express = require('express'); async function checkAuth(req, res, next) { const { token } = req.body; @@ -23,6 +24,30 @@ async function checkAuth(req, res, next) { } } +const router = express.Router(); +const sockets = new Set(); + +router.ws('/', function(ws, req) { + sockets.add(ws); + + ws.on('close', () => { + sockets.delete(ws); + }); +}); + +function socketsMiddleware(req, res, next) { + req.sockets = { + emit: function(data) { + for (const socket of sockets) { + socket.send(JSON.stringify(data)); + } + } + }; + next(); +} + module.exports = { checkAuth, + router, + socketsMiddleware, }; \ No newline at end of file diff --git a/front/src/pages/ChannelPage.tsx b/front/src/pages/ChannelPage.tsx index 0f2c4c9..221767f 100644 --- a/front/src/pages/ChannelPage.tsx +++ b/front/src/pages/ChannelPage.tsx @@ -71,17 +71,28 @@ export default function ChannelPage() { }, [name]); useEffect(() => { - const socket = new WebSocket(`/api/channels/${name}`); + const socket = new WebSocket(`/api/ws`); + + const id = setInterval(() => { + socket.send(JSON.stringify("ping")); + }, 10000); socket.addEventListener('message', function (event) { - if (event.data === "new_message" || event.data === "delete_message") { + const data = JSON.parse(event.data); + console.log(data); + if ((data.type === "new_message" || data.type === "delete_message") && data.channel_id === channel?.id) { axios .get(`/api/channels/${name}/messages`).then((res) => { setMessages(res.data) }) } }); - }, [name]) + + return () => { + clearInterval(id); + socket.close(); + } + }, [channel]) useEffect(() => { const words = message.toString().split(" "); diff --git a/front/src/pages/ChannelsPage.tsx b/front/src/pages/ChannelsPage.tsx index 5d04e95..f4964b3 100644 --- a/front/src/pages/ChannelsPage.tsx +++ b/front/src/pages/ChannelsPage.tsx @@ -34,10 +34,15 @@ export default function ChannelsPage() { }, []) useEffect(() => { - const socket = new WebSocket("/api/channels"); + const socket = new WebSocket("/api/ws"); + + const id = setInterval(() => { + socket.send(JSON.stringify("ping")); + }, 10000); socket.addEventListener('message', function (event) { - if (event.data === "new_channel") { + const data = JSON.parse(event.data); + if (data.type === "new_channel") { axios .get("/api/channels") .then((res) => { @@ -48,6 +53,11 @@ export default function ChannelsPage() { }) } }); + + return () => { + clearInterval(id); + socket.close(); + } }, []) if (!channels) { diff --git a/front/src/pages/Home.tsx b/front/src/pages/Home.tsx index 2517fa6..334f3bb 100644 --- a/front/src/pages/Home.tsx +++ b/front/src/pages/Home.tsx @@ -59,10 +59,16 @@ export default function Home() { }, []) useEffect(() => { - const socket = new WebSocket("/api/channels"); + const socket = new WebSocket("/api/ws"); - socket.addEventListener('message', function (event) { - if (event.data === "new_message" || event.data === "delete_message") { + const id = setInterval(() => { + socket.send(JSON.stringify("ping")); + }, 10000); + + socket.addEventListener('message', function (event) + { + const data = JSON.parse(event.data); + if (data.type === "new_message" || data.type === "delete_message") { axios .get("/api/lastmessages") .then((res) => { @@ -80,7 +86,7 @@ export default function Home() { .catch((err) => { console.error(err.response) }) - } else if (event.data === "new_channel") { + } else if (data.type === "new_channel") { axios .get("/api/activechannels") .then((res) => { @@ -100,6 +106,11 @@ export default function Home() { }) } }); + + return () => { + clearInterval(id); + socket.close(); + } }, []) useEffect(() => { diff --git a/front/src/pages/UserPage.tsx b/front/src/pages/UserPage.tsx index 4971951..fc974f5 100644 --- a/front/src/pages/UserPage.tsx +++ b/front/src/pages/UserPage.tsx @@ -25,17 +25,62 @@ export default function UserPage() { }, []); useEffect(() => { - axios.get(`/api/users/${username}`).then((res) => { - setPageUser(res.data); - }); + axios + .get(`/api/users/${username}`) + .then((res) => { + setPageUser(res.data); + }) + .catch((err) => { + console.error(err.response); + }); - axios.get(`/api/users/${username}/lastmessages`).then((res) => { - setMessages(res.data); - }); + axios + .get(`/api/users/${username}/lastmessages`) + .then((res) => { + setMessages(res.data); + }) + .catch((err) => { + console.error(err.response); + }); }, [username]); + useEffect(() => { + const socket = new WebSocket("/api/ws"); + + const id = setInterval(() => { + socket.send(JSON.stringify("ping")); + }, 10000); + + socket.addEventListener('message', function (event) { + const data = JSON.parse(event.data); + if ((data.type === "new_message" || data.type === "delete_message") && data.user_id === pageUser?.id) { + console.log("new message"); + axios + .get(`/api/users/${username}/lastmessages`) + .then((res) => { + setMessages(res.data); + }) + .catch((err) => { + console.error(err.response); + }); + } + }); + + return () => { + clearInterval(id); + socket.close(); + }; + }, [pageUser]); + if (!pageUser) { - return