websocket-server.ts 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. /* eslint-disable @typescript-eslint/no-explicit-any */
  2. import { WebSocketServer, WebSocket } from 'ws';
  3. import { Server } from 'http';
  4. import { ImportProgress } from './types';
  5. export class ImportProgressServer {
  6. private wss: WebSocketServer | null = null;
  7. private clients: Set<WebSocket> = new Set();
  8. constructor() {
  9. // Initialize WebSocket server
  10. this.setupWebSocketServer();
  11. }
  12. private setupWebSocketServer() {
  13. // This will be initialized when the HTTP server is available
  14. // For now, we'll create a standalone WebSocket server
  15. this.wss = new WebSocketServer({ port: 8080 });
  16. this.wss.on('connection', (ws: WebSocket) => {
  17. console.log('New WebSocket connection established');
  18. this.clients.add(ws);
  19. ws.on('close', () => {
  20. console.log('WebSocket connection closed');
  21. this.clients.delete(ws);
  22. });
  23. ws.on('error', (error) => {
  24. console.error('WebSocket error:', error);
  25. this.clients.delete(ws);
  26. });
  27. });
  28. console.log('WebSocket server started on port 8080');
  29. }
  30. // Alternative method to attach to existing HTTP server
  31. attachToServer(server: Server) {
  32. if (this.wss) {
  33. this.wss.close();
  34. }
  35. this.wss = new WebSocketServer({
  36. server,
  37. path: '/api/imports/progress'
  38. });
  39. this.wss.on('connection', (ws: WebSocket, request) => {
  40. console.log('New WebSocket connection on import progress endpoint');
  41. this.clients.add(ws);
  42. // Handle specific import ID subscriptions
  43. const url = new URL(request.url || '', `http://${request.headers.host}`);
  44. const importId = url.searchParams.get('importId');
  45. if (importId) {
  46. ws.send(JSON.stringify({
  47. type: 'connected',
  48. importId: parseInt(importId),
  49. message: 'Connected to import progress updates'
  50. }));
  51. }
  52. ws.on('close', () => {
  53. console.log('WebSocket connection closed');
  54. this.clients.delete(ws);
  55. });
  56. ws.on('error', (error) => {
  57. console.error('WebSocket error:', error);
  58. this.clients.delete(ws);
  59. });
  60. });
  61. }
  62. broadcastProgress(importId: number, progress: ImportProgress) {
  63. const message = JSON.stringify({
  64. type: 'progress',
  65. importId,
  66. progress
  67. });
  68. this.clients.forEach(client => {
  69. if (client.readyState === WebSocket.OPEN) {
  70. client.send(message);
  71. }
  72. });
  73. }
  74. broadcastError(importId: number, error: string) {
  75. const message = JSON.stringify({
  76. type: 'error',
  77. importId,
  78. error
  79. });
  80. this.clients.forEach(client => {
  81. if (client.readyState === WebSocket.OPEN) {
  82. client.send(message);
  83. }
  84. });
  85. }
  86. broadcastComplete(importId: number, result: any) {
  87. const message = JSON.stringify({
  88. type: 'complete',
  89. importId,
  90. result
  91. });
  92. this.clients.forEach(client => {
  93. if (client.readyState === WebSocket.OPEN) {
  94. client.send(message);
  95. }
  96. });
  97. }
  98. close() {
  99. if (this.wss) {
  100. this.wss.close();
  101. this.clients.clear();
  102. }
  103. }
  104. }
  105. // Export a singleton instance
  106. export const progressServer = new ImportProgressServer();