router_io.ts 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. import { Socket, Server } from "socket.io";
  2. import { Auth } from '@d8d-appcontainer/auth';
  3. import type { User as AuthUser } from '@d8d-appcontainer/auth';
  4. import { APIClient } from '@d8d-appcontainer/api';
  5. import { setupMessageEvents } from './routes_io_messages.ts';
  6. import debug from "debug";
  7. const log = debug('socketio:auth');
  8. interface SetupSocketIOProps {
  9. io: Server, auth: Auth, apiClient: APIClient
  10. }
  11. export interface SocketWithUser extends Socket {
  12. user?: AuthUser;
  13. }
  14. // 定义自定义上下文类型
  15. export interface Variables {
  16. socket: SocketWithUser
  17. auth: Auth
  18. user: AuthUser
  19. apiClient: APIClient
  20. // moduleDir: string
  21. // systemSettings?: SystemSettingRecord
  22. }
  23. export function setupSocketIO({ io, auth, apiClient }:SetupSocketIOProps) {
  24. // Socket.IO认证中间件
  25. io.use(async (socket: SocketWithUser) => {
  26. try {
  27. const token = socket.handshake.query.get('socket_token');
  28. if (!token) {
  29. log(`未提供token,拒绝连接: ${socket.id}`);
  30. throw new Error('未授权')
  31. }
  32. const userData = await auth.verifyToken(token);
  33. if (!userData) {
  34. log(`无效token,拒绝连接: ${socket.id}`);
  35. throw new Error('无效凭证')
  36. }
  37. socket.user = userData;
  38. log(`认证成功: ${socket.id} 用户: ${userData.username}`);
  39. } catch (error) {
  40. log(`认证错误: ${socket.id}`, error);
  41. }
  42. });
  43. io.on("connection", (socket: SocketWithUser) => {
  44. if (!socket.user) {
  45. socket.disconnect(true);
  46. return;
  47. }
  48. console.log(`socket ${socket.id} 已连接,用户: ${socket.user.username}`);
  49. socket.on("disconnect", (reason) => {
  50. console.log(`socket ${socket.id} 断开连接,原因: ${reason}`);
  51. });
  52. const context: Variables = {
  53. socket,
  54. auth,
  55. apiClient,
  56. user: socket.user,
  57. }
  58. // 初始化消息路由
  59. setupMessageEvents(context);
  60. });
  61. }