From 61c2ac14aff391d6d89b7bf70831e498f6592287 Mon Sep 17 00:00:00 2001 From: talksik Date: Fri, 6 May 2022 10:15:58 -0500 Subject: [PATCH] handling connections in general, and so now we have two rooms to manage --- packages/api/sockets/index.ts | 106 +++++------------- packages/core/sockets/channels.ts | 21 +++- .../src/controller/lineDataProvider.tsx | 45 +++++--- 3 files changed, 77 insertions(+), 95 deletions(-) diff --git a/packages/api/sockets/index.ts b/packages/api/sockets/index.ts index e37f47c..3f1e583 100644 --- a/packages/api/sockets/index.ts +++ b/packages/api/sockets/index.ts @@ -1,6 +1,8 @@ import SocketChannels, { ConnectToLine, SomeoneConnected, + SomeoneTuned, + TuneToLine, } from "@nirvana/core/sockets/channels"; import GetAllSocketClients from "@nirvana/core/sockets/getAllActiveSocketClients"; @@ -9,6 +11,7 @@ import ReceiveSignal from "@nirvana/core/sockets/receiveSignal"; import SendSignal from "@nirvana/core/sockets/sendSignal"; import { UserService } from "../services/user.service"; import { UserStatus } from "@nirvana/core/models/user.model"; +import { client } from "../services/database.service"; import { loadConfig } from "../config"; const jwt = require("jsonwebtoken"); @@ -55,100 +58,42 @@ export default function InitializeWs(io: any) { // ?verification that user is in a particular line to be tuned into it or just generally in it? - // regular socket rooms for information for all clients in a specific line - - // another namespace or so for clients tuned into certain lines - - // ===== JOIN ==== - /** User wants to subscribe to live emissions of a conversation */ + /** CONNECT | User wants to subscribe to live emissions of a line */ socket.on(SocketChannels.CONNECT_TO_LINE, (req: ConnectToLine) => { // add this user to the room - console.log(`${socket.id} user joined room for line ${req.lineId}`); - socket.join(req.lineId); + const roomName = `connectedLine:${req.lineId}`; + socket.join(roomName); console.log(`${socket.id} now in rooms ${socket.rooms}`); - io.in(req.lineId).emit( + const clientUserIdsInRoom = [...io.sockets.adapter.rooms.get(roomName)]; + + io.in(roomName).emit( SocketChannels.SOMEONE_CONNECTED_TO_LINE, - new SomeoneConnected(req.lineId, userInfo.userId) + new SomeoneConnected(req.lineId, userInfo.userId, clientUserIdsInRoom) ); }); - // ==== UPDATES ==== - // can be a change of: - // 1. status...later...do short polling for this instead - // 2. new content: audio clip or link - // 3. someone is starting to speak - // send message to everyone in room except sender... + /** TUNE | User tunes into the line either temporarily or toggled in */ + socket.on(SocketChannels.TUNE_TO_LINE, (req: TuneToLine) => { + console.log(`${socket.id} user tuned into room for line ${req.lineId}`); - /** User wants to send some update to a particular room */ - socket.on( - SocketChannels.SEND_AUDIO_CLIP, - (relationshipId: string, audioChunks: any) => { - console.log( - `new audio chunks received..routing to appropriate room!` - ); - console.log(relationshipId); - console.log(audioChunks); + const roomName = `tunedLine:${req.lineId}`; + socket.join(roomName); - io.in(relationshipId).emit( - SocketChannels.SEND_AUDIO_CLIP, - relationshipId, - audioChunks - ); - } - ); + console.log(`${socket.id} now in rooms ${socket.rooms}`); - // tell everyone in a room when someone is starting to speak - socket.on( - SocketChannels.SEND_STARTED_SPEAKING, - (relationshipId: string) => { - console.log(`started speaking in ${relationshipId}`); - io.in(relationshipId).emit( - SocketChannels.SEND_STARTED_SPEAKING, - relationshipId - ); - } - ); + const clientUserIdsInRoom = io.sockets.adapter.rooms + .get(roomName) + .map((socketId: any) => socketIdsToUserIds[socketId]); - // tell everyone in a room when someone is stopping to speak - socket.on( - SocketChannels.SEND_STOPPED_SPEAKING, - (relationshipId: string) => { - console.log(`stopped speaking in ${relationshipId}`); - io.in(relationshipId).emit( - SocketChannels.SEND_STOPPED_SPEAKING, - relationshipId - ); - } - ); - - // change of user status to all of users' rooms and db update - socket.on( - SocketChannels.SEND_USER_STATUS_UPDATE, - async (userGoogleId: string, newStatus: UserStatus) => { - console.log("new status for user"); - - const resultUpdate = await UserService.updateUserStatus( - userGoogleId, - newStatus - ); - - // tell all rooms that the user is part of - // that this user has updated their status - if (resultUpdate?.modifiedCount) { - socket.rooms.forEach((roomId: string) => { - io.in(roomId).emit( - SocketChannels.SEND_USER_STATUS_UPDATE, - userGoogleId, - newStatus - ); - }); - } - } - ); + io.in(roomName).emit( + SocketChannels.SOMEONE_TUNED_TO_LINE, + new SomeoneTuned(req.lineId, userInfo.userId, clientUserIdsInRoom) + ); + }); socket.on(SocketChannels.JOIN_LIVE_ROOM, async () => { // TODO: only get the socket ids of the relevant rooms for this user @@ -179,6 +124,9 @@ export default function InitializeWs(io: any) { socket.on("disconnect", () => { delete socketIdsToUserIds[socket.id]; + // get all of the rooms of this socket + // notify everyone of this disconnection + console.log("user disconnected"); }); }); diff --git a/packages/core/sockets/channels.ts b/packages/core/sockets/channels.ts index f9ba516..819cab6 100644 --- a/packages/core/sockets/channels.ts +++ b/packages/core/sockets/channels.ts @@ -18,8 +18,10 @@ enum SocketChannels { * when someone connects to a line, whether tuned in or not */ CONNECT_TO_LINE = "CONNECT_TO_LINE", - SOMEONE_CONNECTED_TO_LINE = "SOMEONE_CONNECTED_TO_LINE", + + TUNE_TO_LINE = "TUNE_TO_LINE", + SOMEONE_TUNED_TO_LINE = "SOMEONE_TUNED_TO_LINE", } export default SocketChannels; @@ -28,5 +30,20 @@ export class ConnectToLine { constructor(public lineId: string) {} } export class SomeoneConnected { - constructor(public lineId: string, public userId: string) {} + constructor( + public lineId: string, + public userId: string, + public allConnectedIntoUserIds: string[] + ) {} +} + +export class TuneToLine { + constructor(public lineId: string, public keepTunedIn: boolean = false) {} +} +export class SomeoneTuned { + constructor( + public lineId: string, + public userId: string, + public allTunedIntoUserIds: string[] + ) {} } diff --git a/packages/desktop/src/controller/lineDataProvider.tsx b/packages/desktop/src/controller/lineDataProvider.tsx index 7c94c10..3185835 100644 --- a/packages/desktop/src/controller/lineDataProvider.tsx +++ b/packages/desktop/src/controller/lineDataProvider.tsx @@ -2,6 +2,7 @@ import { $jwtToken, $selectedLineId } from "./recoil"; import { ConnectToLine, SomeoneConnected, + SomeoneTuned, } from "@nirvana/core/sockets/channels"; import React, { useContext } from "react"; import { Socket, io } from "socket.io-client"; @@ -39,7 +40,6 @@ export function LineDataProvider({ children }) { // ?just do simple synchronous axios/fetch in useEffect and manage isLoading ourselves? const { data: basicUserLinesData } = useUserLines(); const jwtToken = useRecoilValue($jwtToken); - const selectedLineId = useRecoilValue($selectedLineId); const [linesMap, setLinesMap] = useState({}); @@ -61,14 +61,34 @@ export function LineDataProvider({ children }) { queryClient.invalidateQueries("SERVER_CHECK"); }); + // when me or anyone just initially connects to line $ws.on( SocketChannels.SOMEONE_CONNECTED_TO_LINE, (res: SomeoneConnected) => { toast( - `another user (${res.userId}) tuned into line ${res.lineId} that you are in also` + `another user (${res.userId}) connected into line ${res.lineId} that you are in also connected to` + ); + + // change the correct masterLineData to contain this + + console.log( + `here are all of the users in the tuned in room`, + res.allConnectedIntoUserIds ); } ); + + // whether toggle tuned or temporarily + $ws.on(SocketChannels.SOMEONE_TUNED_TO_LINE, (res: SomeoneTuned) => { + toast( + `another user (${res.userId}) tuned into line ${res.lineId} that you are in also` + ); + + console.log( + `here are all of the users in the tuned in room`, + res.allTunedIntoUserIds + ); + }); }, []); // connect through ws to enrich basic lines data @@ -94,6 +114,10 @@ export function LineDataProvider({ children }) { basicUserLinesData.data.masterLines.map((masterLine) => { newMap[masterLine.lineDetails._id.toString()] = masterLine; + + handleConnect(masterLine.lineDetails._id.toString()); + + // tune into lines }); return newMap; @@ -101,27 +125,20 @@ export function LineDataProvider({ children }) { } }, [basicUserLinesData]); - // on change of line Id, we want to toggle tune into the line - useEffect(() => { - if (selectedLineId) handleToggleTune(selectedLineId, true, true); - }, [selectedLineId]); + const handleConnect = (lineId: string) => { + $ws.emit(SocketChannels.CONNECT_TO_LINE, new ConnectToLine(lineId)); + }; /** * toggle into a specific line * @param temporary: denotes whether we are just listening in or want to persist "toggling" it on so that it shows up in overlay * TODO: have loading state for this particular part of context value */ - - const handleToggleTune = ( - lineId: string, - turnOn: boolean = true, - temporary: boolean = true - ) => { + const handleTune = (lineId: string, turnToggleOn: boolean = false) => { // they already are in the socket room for updates including media connections and disconnections // but set the flag so that the line row can know whether or not to start the webrtc process // and know when to get out or disconnect from the webrtc when the flag turns off - - $ws.emit(SocketChannels.CONNECT_TO_LINE, new ConnectToLine(lineId)); + // $ws.emit(SocketChannels.TUNE_INTO_LINE, new TuneIntoLine(lineId)); }; /**