Files
nirvana-v3/packages/api/index.ts
T

132 lines
3.6 KiB
TypeScript

import express, { Application, Request, Response } from "express";
import { NextFunction } from "express";
import SocketChannels from "@nirvana/core/sockets/channels";
import { UserService } from "./services/user.service";
import { UserStatus } from "@nirvana/core/models";
import cors from "cors";
import getConversationRoutes from "./routes/conversation";
import getSearchRoutes from "./routes/search";
import getUserRoutes from "./routes/user";
const app = express();
app.use(cors());
app.use(express.json());
app.use((req: Request, res: Response, next: NextFunction) => {
console.log("Time: ", Date.now());
next();
});
app.get("/", (req: Request, res: Response) => {
res.send("hello world.");
});
app.use("/api/user", getUserRoutes());
app.use("/api/search", getSearchRoutes());
app.use("/api/conversations", getConversationRoutes());
const PORT = 5000;
var server = app.listen(PORT, () => console.log("express running"));
// socket IO stuff
const io = require("socket.io")(server, {
// todo: add protection
cors: {
origin: "*",
},
});
io.on("connection", function (socket: any) {
// add to map between between googleUserIds and socketId
console.log("a user connected");
// ===== 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
);
});
}
}
);
// ==== DISCONNECT ====
socket.on("disconnect", () => {
console.log("user disconnected");
});
});