Skip to content

Commit

Permalink
Merge pull request #47 from CS3219-AY2425S1/collab-svc-lynn
Browse files Browse the repository at this point in the history
Collab service
  • Loading branch information
lynnetteeee authored Nov 4, 2024
2 parents fb56977 + 06baa8e commit 1b8dc57
Show file tree
Hide file tree
Showing 54 changed files with 3,158 additions and 89 deletions.
1 change: 1 addition & 0 deletions code-websocket/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/node_modules
24 changes: 24 additions & 0 deletions code-websocket/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Use an official Node.js runtime as a parent image
FROM node:18

# Set the working directory
WORKDIR /app

# Copy package.json and package-lock.json (if available)
COPY package*.json ./

# Install dependencies
RUN npm install

# Copy the rest of the application code
COPY . .

# Expose the port the app runs on
EXPOSE 8081

# Define the command to run the app
CMD ["node", "server.js"]


# docker build -t websocket-server .
# docker run -p 8081:8081 websocket-server
33 changes: 33 additions & 0 deletions code-websocket/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions code-websocket/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"dependencies": {
"ws": "^8.18.0"
}
}
92 changes: 92 additions & 0 deletions code-websocket/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
const WebSocket = require('ws');
const server = new WebSocket.Server({ port: 8081 });

// Store the code for each session ID
const sessionData = {};
const activeUsers = {};
server.on('connection', (socket, request) => {
const urlParts = request.url.split('/');
const sessionID = urlParts.pop().split('?')[0];
const userID = new URLSearchParams(request.url.split('?')[1]).get('userID');

// Initialize session data if it doesn't exist
if (!sessionData[sessionID]) {
sessionData[sessionID] = { code: '' };
}

if (!activeUsers[sessionID]) {
activeUsers[sessionID] = {};
}

activeUsers[sessionID][userID] = socket;
console.log(`User ${userID} connected to session ${sessionID}`);

broadcastToSession(sessionID, {
type: 'userConnected',
userID,
});

// Send the current code to the newly connected client
socket.send(JSON.stringify({ type: 'initialCode', content: sessionData[sessionID].code }));

// Handle incoming messages
socket.on('message', (message) => {
const parsedMessage = JSON.parse(message);
console.log(`Received message from user ${userID} in session ${sessionID}:`, parsedMessage);

if (parsedMessage.type === 'code') {
// Update the stored code for this session
sessionData[sessionID].code = parsedMessage.content;

// Broadcast the updated code to all clients in the same session
broadcastToSession(sessionID, {
type: 'code',
content: parsedMessage.content
}, socket);
}
});

// Handle client disconnection
socket.on('close', (code, reason) => {
console.log(`User ${userID} disconnected from session ${sessionID}, code: ${code}, reason: ${reason}`);

// Remove the user from the active users list
delete activeUsers[sessionID][userID];

// Log the remaining users in the session
const remainingUsers = Object.keys(activeUsers[sessionID]);
console.log(`Remaining users in session ${sessionID}: ${remainingUsers.length > 0 ? remainingUsers.join(', ') : 'None'}`);


broadcastToSession(sessionID, {
type: 'userDisconnected',
userID,
});

if (remainingUsers.length === 0) {
console.log(`All users disconnected from session ${sessionID}. Removing session data.`);

// Remove the session data and active users entry for this session
delete sessionData[sessionID];
delete activeUsers[sessionID];
}
});

// Handle errors
socket.on('error', (error) => {
console.error(`Socket error for user ${userID} in session ${sessionID}:`, error);
});


});


function broadcastToSession(sessionID, message, excludeSocket = null) {
Object.values(activeUsers[sessionID]).forEach((clientSocket) => {
if (clientSocket.readyState === WebSocket.OPEN && clientSocket !== excludeSocket) {
clientSocket.send(JSON.stringify(message));
}
});
}

console.log('WebSocket server is running on ws://localhost:8081');
46 changes: 44 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
version: "3.8"

services:
question:
image: golang:1.23-alpine
Expand All @@ -16,6 +14,8 @@ services:
- CGO_ENABLED=0
depends_on:
- mongo
networks:
- ihatefrontend

user:
image: node:18-alpine
Expand All @@ -30,6 +30,8 @@ services:
- "3001:3001"
depends_on:
- mongo
networks:
- ihatefrontend

mongo:
image: mongo:6.0
Expand All @@ -38,6 +40,8 @@ services:
- mongo_data:/data/db
ports:
- "27017:27017"
networks:
- ihatefrontend

rabbitmq:
image: node:18-alpine
Expand All @@ -55,10 +59,48 @@ services:
- 3002:3002
networks:
- rabbitmqNetwork
- ihatefrontend

collaboration:
image: node:16-alpine
container_name: peer-prep-collab
working_dir: /app
env_file:
- ./peer-prep-collab/.env
volumes:
- ./peer-prep-collab:/app
command: sh -c "npm install && npm start"
ports:
- "4003:4003"
depends_on:
- mongo
- question
- rabbitmq
environment:
- QUESTIONS_SERVICE_URL=http://question:8080
- RABBITMQ_URL=http://rabbitmq:3002
- AMQP_SERVER=amqps://lguugvwb:[email protected]/lguugvwb
networks:
- rabbitmqNetwork
- ihatefrontend

websocket:
image: node:18-alpine
container_name: collab-websocket
volumes:
- ./code-websocket:/app
working_dir: /app
command: sh -c "npm install && npm start"
ports:
- "8081:8081"
networks:
- ihatefrontend

networks:
rabbitmqNetwork:
driver: bridge
ihatefrontend:
driver: bridge

volumes:
mongo_data:
Expand Down
2 changes: 1 addition & 1 deletion message-queue/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions peer-prep-collab/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules/

.env
29 changes: 29 additions & 0 deletions peer-prep-collab/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Use the official Node.js image as the base
FROM node:16-alpine

# Define environment variables if needed
ENV PORT=4003
ENV MATCHING_SERVICE_URL=http://localhost:3002
ENV QUESTIONS_SERVICE_URL=http://localhost:8080
ENV AMQP_SERVER=amqps://lguugvwb:[email protected]/lguugvwb

# Set the working directory in the container
WORKDIR /app

# Copy package.json and package-lock.json into the container
COPY package*.json ./

# Install dependencies
RUN npm install

# Copy the rest of your application code into the container
COPY . .

# Expose the port your app runs on
EXPOSE 4003

# Start the application
# CMD ["npm", "start"]

# docker build -t peer-prep-collab .
# docker run -p 4003:4003 peer-prep-collab
Loading

0 comments on commit 1b8dc57

Please sign in to comment.