handling connections in general, and so now we have two rooms to manage
This commit is contained in:
@@ -1,6 +1,8 @@
|
|||||||
import SocketChannels, {
|
import SocketChannels, {
|
||||||
ConnectToLine,
|
ConnectToLine,
|
||||||
SomeoneConnected,
|
SomeoneConnected,
|
||||||
|
SomeoneTuned,
|
||||||
|
TuneToLine,
|
||||||
} from "@nirvana/core/sockets/channels";
|
} from "@nirvana/core/sockets/channels";
|
||||||
|
|
||||||
import GetAllSocketClients from "@nirvana/core/sockets/getAllActiveSocketClients";
|
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 SendSignal from "@nirvana/core/sockets/sendSignal";
|
||||||
import { UserService } from "../services/user.service";
|
import { UserService } from "../services/user.service";
|
||||||
import { UserStatus } from "@nirvana/core/models/user.model";
|
import { UserStatus } from "@nirvana/core/models/user.model";
|
||||||
|
import { client } from "../services/database.service";
|
||||||
import { loadConfig } from "../config";
|
import { loadConfig } from "../config";
|
||||||
|
|
||||||
const jwt = require("jsonwebtoken");
|
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?
|
// ?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
|
/** CONNECT | User wants to subscribe to live emissions of a line */
|
||||||
|
|
||||||
// another namespace or so for clients tuned into certain lines
|
|
||||||
|
|
||||||
// ===== JOIN ====
|
|
||||||
/** User wants to subscribe to live emissions of a conversation */
|
|
||||||
socket.on(SocketChannels.CONNECT_TO_LINE, (req: ConnectToLine) => {
|
socket.on(SocketChannels.CONNECT_TO_LINE, (req: ConnectToLine) => {
|
||||||
// add this user to the room
|
// add this user to the room
|
||||||
|
|
||||||
console.log(`${socket.id} user joined room for line ${req.lineId}`);
|
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}`);
|
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,
|
SocketChannels.SOMEONE_CONNECTED_TO_LINE,
|
||||||
new SomeoneConnected(req.lineId, userInfo.userId)
|
new SomeoneConnected(req.lineId, userInfo.userId, clientUserIdsInRoom)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// ==== UPDATES ====
|
/** TUNE | User tunes into the line either temporarily or toggled in */
|
||||||
// can be a change of:
|
socket.on(SocketChannels.TUNE_TO_LINE, (req: TuneToLine) => {
|
||||||
// 1. status...later...do short polling for this instead
|
console.log(`${socket.id} user tuned into room for line ${req.lineId}`);
|
||||||
// 2. new content: audio clip or link
|
|
||||||
// 3. someone is starting to speak
|
|
||||||
// send message to everyone in room except sender...
|
|
||||||
|
|
||||||
/** User wants to send some update to a particular room */
|
const roomName = `tunedLine:${req.lineId}`;
|
||||||
socket.on(
|
socket.join(roomName);
|
||||||
SocketChannels.SEND_AUDIO_CLIP,
|
|
||||||
(relationshipId: string, audioChunks: any) => {
|
|
||||||
console.log(
|
|
||||||
`new audio chunks received..routing to appropriate room!`
|
|
||||||
);
|
|
||||||
console.log(relationshipId);
|
|
||||||
console.log(audioChunks);
|
|
||||||
|
|
||||||
io.in(relationshipId).emit(
|
console.log(`${socket.id} now in rooms ${socket.rooms}`);
|
||||||
SocketChannels.SEND_AUDIO_CLIP,
|
|
||||||
relationshipId,
|
|
||||||
audioChunks
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// tell everyone in a room when someone is starting to speak
|
const clientUserIdsInRoom = io.sockets.adapter.rooms
|
||||||
socket.on(
|
.get(roomName)
|
||||||
SocketChannels.SEND_STARTED_SPEAKING,
|
.map((socketId: any) => socketIdsToUserIds[socketId]);
|
||||||
(relationshipId: string) => {
|
|
||||||
console.log(`started speaking in ${relationshipId}`);
|
|
||||||
io.in(relationshipId).emit(
|
|
||||||
SocketChannels.SEND_STARTED_SPEAKING,
|
|
||||||
relationshipId
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// tell everyone in a room when someone is stopping to speak
|
io.in(roomName).emit(
|
||||||
socket.on(
|
SocketChannels.SOMEONE_TUNED_TO_LINE,
|
||||||
SocketChannels.SEND_STOPPED_SPEAKING,
|
new SomeoneTuned(req.lineId, userInfo.userId, clientUserIdsInRoom)
|
||||||
(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
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
socket.on(SocketChannels.JOIN_LIVE_ROOM, async () => {
|
socket.on(SocketChannels.JOIN_LIVE_ROOM, async () => {
|
||||||
// TODO: only get the socket ids of the relevant rooms for this user
|
// 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", () => {
|
socket.on("disconnect", () => {
|
||||||
delete socketIdsToUserIds[socket.id];
|
delete socketIdsToUserIds[socket.id];
|
||||||
|
|
||||||
|
// get all of the rooms of this socket
|
||||||
|
// notify everyone of this disconnection
|
||||||
|
|
||||||
console.log("user disconnected");
|
console.log("user disconnected");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -18,8 +18,10 @@ enum SocketChannels {
|
|||||||
* when someone connects to a line, whether tuned in or not
|
* when someone connects to a line, whether tuned in or not
|
||||||
*/
|
*/
|
||||||
CONNECT_TO_LINE = "CONNECT_TO_LINE",
|
CONNECT_TO_LINE = "CONNECT_TO_LINE",
|
||||||
|
|
||||||
SOMEONE_CONNECTED_TO_LINE = "SOMEONE_CONNECTED_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;
|
export default SocketChannels;
|
||||||
@@ -28,5 +30,20 @@ export class ConnectToLine {
|
|||||||
constructor(public lineId: string) {}
|
constructor(public lineId: string) {}
|
||||||
}
|
}
|
||||||
export class SomeoneConnected {
|
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[]
|
||||||
|
) {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { $jwtToken, $selectedLineId } from "./recoil";
|
|||||||
import {
|
import {
|
||||||
ConnectToLine,
|
ConnectToLine,
|
||||||
SomeoneConnected,
|
SomeoneConnected,
|
||||||
|
SomeoneTuned,
|
||||||
} from "@nirvana/core/sockets/channels";
|
} from "@nirvana/core/sockets/channels";
|
||||||
import React, { useContext } from "react";
|
import React, { useContext } from "react";
|
||||||
import { Socket, io } from "socket.io-client";
|
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?
|
// ?just do simple synchronous axios/fetch in useEffect and manage isLoading ourselves?
|
||||||
const { data: basicUserLinesData } = useUserLines();
|
const { data: basicUserLinesData } = useUserLines();
|
||||||
const jwtToken = useRecoilValue($jwtToken);
|
const jwtToken = useRecoilValue($jwtToken);
|
||||||
const selectedLineId = useRecoilValue($selectedLineId);
|
|
||||||
|
|
||||||
const [linesMap, setLinesMap] = useState<LineIdToMasterLine>({});
|
const [linesMap, setLinesMap] = useState<LineIdToMasterLine>({});
|
||||||
|
|
||||||
@@ -61,14 +61,34 @@ export function LineDataProvider({ children }) {
|
|||||||
queryClient.invalidateQueries("SERVER_CHECK");
|
queryClient.invalidateQueries("SERVER_CHECK");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// when me or anyone just initially connects to line
|
||||||
$ws.on(
|
$ws.on(
|
||||||
SocketChannels.SOMEONE_CONNECTED_TO_LINE,
|
SocketChannels.SOMEONE_CONNECTED_TO_LINE,
|
||||||
(res: SomeoneConnected) => {
|
(res: SomeoneConnected) => {
|
||||||
toast(
|
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
|
// connect through ws to enrich basic lines data
|
||||||
@@ -94,6 +114,10 @@ export function LineDataProvider({ children }) {
|
|||||||
|
|
||||||
basicUserLinesData.data.masterLines.map((masterLine) => {
|
basicUserLinesData.data.masterLines.map((masterLine) => {
|
||||||
newMap[masterLine.lineDetails._id.toString()] = masterLine;
|
newMap[masterLine.lineDetails._id.toString()] = masterLine;
|
||||||
|
|
||||||
|
handleConnect(masterLine.lineDetails._id.toString());
|
||||||
|
|
||||||
|
// tune into lines
|
||||||
});
|
});
|
||||||
|
|
||||||
return newMap;
|
return newMap;
|
||||||
@@ -101,27 +125,20 @@ export function LineDataProvider({ children }) {
|
|||||||
}
|
}
|
||||||
}, [basicUserLinesData]);
|
}, [basicUserLinesData]);
|
||||||
|
|
||||||
// on change of line Id, we want to toggle tune into the line
|
const handleConnect = (lineId: string) => {
|
||||||
useEffect(() => {
|
$ws.emit(SocketChannels.CONNECT_TO_LINE, new ConnectToLine(lineId));
|
||||||
if (selectedLineId) handleToggleTune(selectedLineId, true, true);
|
};
|
||||||
}, [selectedLineId]);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* toggle into a specific line
|
* 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
|
* @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
|
* TODO: have loading state for this particular part of context value
|
||||||
*/
|
*/
|
||||||
|
const handleTune = (lineId: string, turnToggleOn: boolean = false) => {
|
||||||
const handleToggleTune = (
|
|
||||||
lineId: string,
|
|
||||||
turnOn: boolean = true,
|
|
||||||
temporary: boolean = true
|
|
||||||
) => {
|
|
||||||
// they already are in the socket room for updates including media connections and disconnections
|
// 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
|
// 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
|
// and know when to get out or disconnect from the webrtc when the flag turns off
|
||||||
|
// $ws.emit(SocketChannels.TUNE_INTO_LINE, new TuneIntoLine(lineId));
|
||||||
$ws.emit(SocketChannels.CONNECT_TO_LINE, new ConnectToLine(lineId));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user