|
|
|
|
|
const express = require('express'); |
|
|
const http = require('http'); |
|
|
const socketIo = require('socket.io'); |
|
|
const cors = require('cors'); |
|
|
|
|
|
const app = express(); |
|
|
app.use(cors()); |
|
|
|
|
|
const server = http.createServer(app); |
|
|
const io = socketIo(server, { |
|
|
cors: { |
|
|
origin: "*", |
|
|
methods: ["GET", "POST"] |
|
|
} |
|
|
}); |
|
|
|
|
|
|
|
|
const MAIN_DOCTOR_ID = 'main_doctor'; |
|
|
|
|
|
|
|
|
const activeUsers = new Map(); |
|
|
const activeChats = new Map(); |
|
|
const patientsList = new Map(); |
|
|
|
|
|
|
|
|
app.get('/', (req, res) => { |
|
|
res.send('Healthcare Chat Server Running'); |
|
|
}); |
|
|
|
|
|
|
|
|
io.on('connection', (socket) => { |
|
|
console.log('New client connected:', socket.id); |
|
|
const userId = socket.handshake.query.userId; |
|
|
const userType = socket.handshake.query.userType || 'patient'; |
|
|
|
|
|
|
|
|
activeUsers.set(userId, socket); |
|
|
|
|
|
console.log(`User connected: ${userId} (${userType})`); |
|
|
|
|
|
|
|
|
if (userType === 'doctor') { |
|
|
|
|
|
const patients = Array.from(patientsList.values()); |
|
|
socket.emit('patientsList', patients); |
|
|
|
|
|
|
|
|
for (const [chatId, chat] of activeChats.entries()) { |
|
|
socket.join(chatId); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (userType === 'patient') { |
|
|
|
|
|
const patientInfo = { |
|
|
id: userId, |
|
|
chatId: `${userId}-${MAIN_DOCTOR_ID}`, |
|
|
lastMessage: '', |
|
|
unreadCount: 0 |
|
|
}; |
|
|
|
|
|
patientsList.set(userId, patientInfo); |
|
|
|
|
|
|
|
|
const doctorSocket = activeUsers.get(MAIN_DOCTOR_ID); |
|
|
if (doctorSocket) { |
|
|
doctorSocket.emit('newPatient', patientInfo); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
socket.on('joinChat', ({ patientId, doctorId }) => { |
|
|
|
|
|
const actualDoctorId = MAIN_DOCTOR_ID; |
|
|
const chatId = `${patientId}-${actualDoctorId}`; |
|
|
|
|
|
|
|
|
if (!activeChats.has(chatId)) { |
|
|
activeChats.set(chatId, { |
|
|
patientId, |
|
|
doctorId: actualDoctorId, |
|
|
messages: [] |
|
|
}); |
|
|
|
|
|
console.log(`New chat created: ${chatId}`); |
|
|
} |
|
|
|
|
|
|
|
|
socket.join(chatId); |
|
|
|
|
|
|
|
|
socket.emit('previousMessages', { |
|
|
chatId, |
|
|
messages: activeChats.get(chatId).messages |
|
|
}); |
|
|
|
|
|
console.log(`User ${userId} joined chat ${chatId}`); |
|
|
}); |
|
|
|
|
|
|
|
|
socket.on('message', (message) => { |
|
|
const { text, chatId, timestamp } = message; |
|
|
|
|
|
|
|
|
if (!activeChats.has(chatId)) { |
|
|
console.log(`Error: Chat ${chatId} not found`); |
|
|
return; |
|
|
} |
|
|
|
|
|
|
|
|
const patientId = chatId.split('-')[0]; |
|
|
|
|
|
|
|
|
const newMessage = { |
|
|
id: Date.now().toString(), |
|
|
text, |
|
|
senderId: userId, |
|
|
senderType: userType, |
|
|
timestamp: timestamp || new Date(), |
|
|
isRead: false |
|
|
}; |
|
|
|
|
|
|
|
|
activeChats.get(chatId).messages.push(newMessage); |
|
|
|
|
|
|
|
|
if (patientsList.has(patientId)) { |
|
|
const patientInfo = patientsList.get(patientId); |
|
|
patientInfo.lastMessage = text; |
|
|
|
|
|
|
|
|
if (userType === 'patient') { |
|
|
|
|
|
const doctorSocket = activeUsers.get(MAIN_DOCTOR_ID); |
|
|
if (doctorSocket && doctorSocket.data.currentChatId !== chatId) { |
|
|
patientInfo.unreadCount++; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
patientsList.set(patientId, patientInfo); |
|
|
|
|
|
|
|
|
const doctorSocket = activeUsers.get(MAIN_DOCTOR_ID); |
|
|
if (doctorSocket) { |
|
|
doctorSocket.emit('patientUpdated', patientInfo); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
io.to(chatId).emit('message', { |
|
|
chatId, |
|
|
message: newMessage |
|
|
}); |
|
|
|
|
|
console.log(`New message in chat ${chatId} from ${userId}: ${text}`); |
|
|
}); |
|
|
|
|
|
|
|
|
socket.on('viewingChat', ({ chatId }) => { |
|
|
if (userType === 'doctor') { |
|
|
socket.data.currentChatId = chatId; |
|
|
|
|
|
|
|
|
const patientId = chatId.split('-')[0]; |
|
|
if (patientsList.has(patientId)) { |
|
|
const patientInfo = patientsList.get(patientId); |
|
|
patientInfo.unreadCount = 0; |
|
|
patientsList.set(patientId, patientInfo); |
|
|
|
|
|
|
|
|
socket.emit('patientUpdated', patientInfo); |
|
|
} |
|
|
} |
|
|
}); |
|
|
|
|
|
|
|
|
socket.on('typing', ({ chatId, isTyping }) => { |
|
|
|
|
|
socket.to(chatId).emit('typing', { |
|
|
chatId, |
|
|
userId, |
|
|
isTyping |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
socket.on('markAsRead', ({ chatId, messageIds }) => { |
|
|
if (activeChats.has(chatId)) { |
|
|
const chat = activeChats.get(chatId); |
|
|
|
|
|
|
|
|
chat.messages.forEach(msg => { |
|
|
if (messageIds.includes(msg.id) && msg.senderId !== userId) { |
|
|
msg.isRead = true; |
|
|
} |
|
|
}); |
|
|
|
|
|
|
|
|
socket.to(chatId).emit('messagesRead', { |
|
|
chatId, |
|
|
messageIds, |
|
|
readBy: userId |
|
|
}); |
|
|
} |
|
|
}); |
|
|
|
|
|
|
|
|
socket.on('disconnect', () => { |
|
|
console.log('Client disconnected:', userId); |
|
|
activeUsers.delete(userId); |
|
|
|
|
|
|
|
|
if (userType === 'patient') { |
|
|
if (patientsList.has(userId)) { |
|
|
const patientInfo = patientsList.get(userId); |
|
|
patientInfo.isOnline = false; |
|
|
patientsList.set(userId, patientInfo); |
|
|
|
|
|
|
|
|
const doctorSocket = activeUsers.get(MAIN_DOCTOR_ID); |
|
|
if (doctorSocket) { |
|
|
doctorSocket.emit('patientUpdated', patientInfo); |
|
|
} |
|
|
} |
|
|
} |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
const PORT = process.env.PORT || 3000; |
|
|
server.listen(PORT, () => { |
|
|
console.log(`Server running on port ${PORT}`) |
|
|
}); |