forked from ttc/micro-service-api
80 lines
2.9 KiB
JavaScript
80 lines
2.9 KiB
JavaScript
|
|
import { verifyToken } from '../utils/token.js'
|
||
|
|
import { SocketController } from '../controllers/socketController.js'
|
||
|
|
import { GeneralService } from '../share/generalservice.js'
|
||
|
|
import redis from '../utils/redis.js' // ใช้ Redis ที่มีเก็บ Session
|
||
|
|
|
||
|
|
export class SocketManager {
|
||
|
|
constructor(io) {
|
||
|
|
this.io = io
|
||
|
|
this.generalService = new GeneralService()
|
||
|
|
this.socketController = new SocketController()
|
||
|
|
}
|
||
|
|
|
||
|
|
initialize() {
|
||
|
|
this.generalService.devhint(1, 'SocketManager.js', 'Initializing Socket.io')
|
||
|
|
|
||
|
|
// Middleware: Authentication (เช็ค Token ก่อน Connect)
|
||
|
|
this.io.use(async (socket, next) => {
|
||
|
|
try {
|
||
|
|
const token = socket.handshake.auth.token || socket.handshake.headers.token
|
||
|
|
if (!token) return next(new Error('Authentication error'))
|
||
|
|
|
||
|
|
const decoded = verifyToken(token)
|
||
|
|
if (!decoded) return next(new Error('Invalid Token'))
|
||
|
|
|
||
|
|
// เก็บข้อมูล User เข้า Socket Session
|
||
|
|
socket.user = decoded
|
||
|
|
socket.organization = decoded.organization // ใช้สำหรับ Schema
|
||
|
|
next()
|
||
|
|
} catch (err) {
|
||
|
|
next(new Error('Authentication failed'))
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
this.io.on('connection', async (socket) => {
|
||
|
|
this.generalService.devhint(1, 'SocketManager.js', `User Connected: ${socket.user.usrnam}`)
|
||
|
|
|
||
|
|
// 1. Save User Session to Redis (Pattern การเก็บ state)
|
||
|
|
// key: "online:user_id", value: socket_id
|
||
|
|
await redis.set(`online:${socket.user.id}`, socket.id)
|
||
|
|
|
||
|
|
// Join Room ส่วนตัว (ตาม User ID)
|
||
|
|
socket.join(socket.user.id.toString())
|
||
|
|
|
||
|
|
// ==========================================
|
||
|
|
// Event Handlers (เรียก Controller Pattern)
|
||
|
|
// ==========================================
|
||
|
|
|
||
|
|
// 1. Send Notification (User ส่งหา User)
|
||
|
|
socket.on('send_notification', async (data) => {
|
||
|
|
await this.socketController.onSendNotification(this.io, socket, data)
|
||
|
|
})
|
||
|
|
|
||
|
|
// 2. VoIP: Call Request
|
||
|
|
socket.on('call_user', async (data) => {
|
||
|
|
await this.socketController.onCallUser(this.io, socket, data)
|
||
|
|
})
|
||
|
|
|
||
|
|
// 3. VoIP: Answer Call
|
||
|
|
socket.on('answer_call', async (data) => {
|
||
|
|
await this.socketController.onAnswerCall(this.io, socket, data)
|
||
|
|
})
|
||
|
|
|
||
|
|
// 4. VoIP: ICE Candidate (Network info)
|
||
|
|
socket.on('ice_candidate', async (data) => {
|
||
|
|
await this.socketController.onIceCandidate(this.io, socket, data)
|
||
|
|
})
|
||
|
|
|
||
|
|
// 5. VoIP: End Call
|
||
|
|
socket.on('end_call', async (data) => {
|
||
|
|
await this.socketController.onEndCall(this.io, socket, data)
|
||
|
|
})
|
||
|
|
|
||
|
|
// Disconnect
|
||
|
|
socket.on('disconnect', async () => {
|
||
|
|
this.generalService.devhint(1, 'SocketManager.js', `User Disconnected: ${socket.user.usrnam}`)
|
||
|
|
await redis.del(`online:${socket.user.id}`)
|
||
|
|
})
|
||
|
|
})
|
||
|
|
}
|
||
|
|
}
|