Spaces:
Sleeping
Sleeping
File size: 1,672 Bytes
ae4ceef | 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 | import { Server as SocketServer } from 'socket.io';
import { Server as HttpServer } from 'http';
import jwt from 'jsonwebtoken';
let io: SocketServer | null = null;
const JWT_SECRET = process.env.JWT_SECRET || 'codex_secret_fallback';
export const initSocket = (server: HttpServer) => {
io = new SocketServer(server, {
cors: {
origin: '*',
methods: ['GET', 'POST']
}
});
// 增加 JWT 鉴权中间件
io.use((socket, next) => {
const token = socket.handshake.auth.token || socket.handshake.headers.token;
if (!token) return next(new Error('未授权'));
try {
const decoded = jwt.verify(token, JWT_SECRET) as any;
(socket as any).user = decoded;
next();
} catch (err) {
next(new Error('Token 无效'));
}
});
io.on('connection', (socket) => {
const user = (socket as any).user;
console.log(`[Socket] 用户已认证并连接: ${user.email} (ID: ${socket.id})`);
// 自动加入用户专属房间
socket.join(`user:${user.userId}`);
socket.on('disconnect', () => {
console.log(`[Socket] 用户断开: ${user.email}`);
});
});
return io;
};
export const getIO = () => {
if (!io) throw new Error('Socket.io 未初始化');
return io;
};
/**
* 推送实时通知给特定用户
*/
export const notifyUser = (userId: string, event: string, data: any) => {
if (io) {
io.to(`user:${userId}`).emit(event, data);
}
};
/**
* 推送广播给所有管理员
*/
export const broadcastAdmin = (event: string, data: any) => {
if (io) {
// 假设管理员在一个特定的房间,或者直接广播
io.emit(`admin:${event}`, data);
}
};
|