-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsocket.js
More file actions
155 lines (135 loc) · 4.22 KB
/
socket.js
File metadata and controls
155 lines (135 loc) · 4.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/**
* Voygo Centralized Socket.io Handler
*
* This module manages all real-time WebSocket communication
* for the modular monolith. It handles:
* - User and Captain connections
* - Location updates for captains
* - Ride notifications
*
* In the monolith architecture, socket calls are internal
* and don't need to go through HTTP - we can call notify() directly.
*/
const { Server } = require("socket.io");
const mongoose = require("mongoose");
// Import models directly for the monolith
// These will be available after mongoose connection is established
let userModel, captainModel;
// Lazy load models to avoid circular dependency issues
const getModels = () => {
if (!userModel) {
userModel = require("./services/users/models/user.model");
}
if (!captainModel) {
captainModel = require("./services/captains/models/captain.model");
}
return { userModel, captainModel };
};
let io;
/**
* Initialize Socket.io server
* @param {http.Server} server - HTTP server instance
*/
const initializeSocket = (server) => {
io = new Server(server, {
cors: {
origin: process.env.FRONTEND_URL || "*",
methods: ["GET", "POST"],
credentials: true
},
});
io.on("connection", (socket) => {
console.log(`🔌 Client connected: ${socket.id}`);
/**
* Handle user or captain joining
* Updates the socketId in the database for the connected user/captain
*/
socket.on("join", async (data) => {
const { userId, userType } = data;
if (!userId || !userType) {
console.error("Join event missing userId or userType");
return;
}
try {
const { userModel, captainModel } = getModels();
if (userType === "user") {
await userModel.findByIdAndUpdate(userId, { socketId: socket.id });
console.log(`👤 User ${userId} joined with socket ${socket.id}`);
} else if (userType === "captain") {
await captainModel.findByIdAndUpdate(userId, { socketId: socket.id });
console.log(`🚗 Captain ${userId} joined with socket ${socket.id}`);
}
} catch (error) {
console.error("Error updating socket ID:", error.message);
}
});
/**
* Handle captain location updates
* Updates the captain's current location in the database
*/
socket.on("update-location-captain", async (data) => {
const { userId, location } = data;
if (!userId || !location || !location.ltd || !location.lng) {
console.error("Location update missing required fields");
return;
}
try {
const { captainModel } = getModels();
await captainModel.findByIdAndUpdate(userId, {
location: {
ltd: location.ltd,
lng: location.lng,
},
});
} catch (error) {
console.error("Error updating captain location:", error.message);
}
});
/**
* Handle client disconnect
*/
socket.on("disconnect", () => {
console.log(`🔌 Client disconnected: ${socket.id}`);
});
});
console.log("✅ Socket.io initialized");
};
/**
* Send a notification to a specific socket
* @param {string} socketId - Target socket ID
* @param {string} event - Event name
* @param {object} data - Data to send
*/
const notify = (socketId, event, data) => {
if (io) {
io.to(socketId).emit(event, data);
console.log(`📤 Notification sent to ${socketId}: ${event}`);
} else {
console.error("Socket.io not initialized - cannot send notification");
}
};
/**
* Send a message to a specific socket
* This is the function used by ride.controller via the socket module
* @param {string} socketId - Target socket ID
* @param {object} message - Message object with event and data properties
*/
const sendMessageToSocketId = (socketId, message) => {
if (io && socketId) {
io.to(socketId).emit(message.event, message.data);
console.log(`📤 Message sent to ${socketId}: ${message.event}`);
} else {
console.error("Socket.io not initialized or socketId missing");
}
};
/**
* Get the Socket.io server instance
* @returns {Server} Socket.io server instance
*/
const getIO = () => io;
module.exports = {
initializeSocket,
notify,
sendMessageToSocketId,
getIO
};