171 lines
5.3 KiB
TypeScript
171 lines
5.3 KiB
TypeScript
import GetAllSocketClients from "@nirvana/core/sockets/getAllActiveSocketClients";
|
|
import { JwtClaims } from "../middleware/auth";
|
|
import ReceiveSignal from "@nirvana/core/sockets/receiveSignal";
|
|
import SendSignal from "@nirvana/core/sockets/sendSignal";
|
|
import SocketChannels from "@nirvana/core/sockets/channels";
|
|
import { UserService } from "../services/user.service";
|
|
import { UserStatus } from "@nirvana/core/models/user.model";
|
|
import { loadConfig } from "../config";
|
|
|
|
const jwt = require("jsonwebtoken");
|
|
|
|
const config = loadConfig();
|
|
|
|
export default function InitializeWs(io: any) {
|
|
console.log("initializing web sockets");
|
|
|
|
return io
|
|
.use(function (socket: any, next: any) {
|
|
console.log("authenticating user...");
|
|
|
|
try {
|
|
const { token } = socket.handshake.query;
|
|
|
|
// verify jwt token with our api secret
|
|
var decoded: JwtClaims = jwt.verify(token, config.JWT_TOKEN_SECRET);
|
|
|
|
socket.userInfo = decoded;
|
|
|
|
next();
|
|
} catch (error) {
|
|
console.error(error);
|
|
next(new Error("WS Authentication Error"));
|
|
}
|
|
})
|
|
.on("connection", function (socket: any) {
|
|
const userInfo: JwtClaims = socket.userInfo;
|
|
|
|
console.log(
|
|
`a user connected | user Id: ${userInfo.userId} and name: ${userInfo.name}`
|
|
);
|
|
|
|
socket.on("test", () => {
|
|
console.log("asdf");
|
|
});
|
|
|
|
// ?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 */
|
|
socket.on(SocketChannels.JOIN_ROOM, (relationshipId: string) => {
|
|
// add this user to the room
|
|
|
|
console.log(
|
|
`${socket.id} user joined room for relationship ${relationshipId}`
|
|
);
|
|
|
|
socket.join(relationshipId);
|
|
|
|
console.log(`${socket.id} now in rooms ${socket.rooms}`);
|
|
});
|
|
|
|
// ==== 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...
|
|
|
|
/** 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);
|
|
|
|
io.in(relationshipId).emit(
|
|
SocketChannels.SEND_AUDIO_CLIP,
|
|
relationshipId,
|
|
audioChunks
|
|
);
|
|
}
|
|
);
|
|
|
|
// 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
|
|
);
|
|
}
|
|
);
|
|
|
|
// 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
|
|
);
|
|
});
|
|
}
|
|
}
|
|
);
|
|
|
|
socket.on(SocketChannels.JOIN_LIVE_ROOM, async () => {
|
|
// TODO: only get the socket ids of the relevant rooms for this user
|
|
// return all Socket instances
|
|
const allConnectedSockets = Array.from(await io.of("/").sockets.keys());
|
|
|
|
io.to(socket.id).emit(SocketChannels.GET_ALL_ACTIVE_SOCKET_IDS, {
|
|
socketIds: allConnectedSockets,
|
|
} as GetAllSocketClients);
|
|
});
|
|
|
|
socket.on(SocketChannels.SEND_SIGNAL, async (payload: SendSignal) => {
|
|
console.log(payload);
|
|
|
|
const sendingBackData: ReceiveSignal = {
|
|
simplePeerSignal: payload.simplePeerSignal,
|
|
senderUserSocketId: socket.id,
|
|
isGoingBackToInitiator: payload.isAnswerer ? true : false,
|
|
};
|
|
|
|
io.to(payload.userSocketIdToSignal).emit(
|
|
SocketChannels.RECEIVE_SIGNAL,
|
|
sendingBackData
|
|
);
|
|
});
|
|
|
|
// ==== DISCONNECT ====
|
|
socket.on("disconnect", () => {
|
|
console.log("user disconnected");
|
|
});
|
|
});
|
|
}
|