134 lines
3.7 KiB
TypeScript
134 lines
3.7 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/user.model";
|
|
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((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");
|
|
|
|
// todo persist status changes
|
|
// 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");
|
|
});
|
|
});
|