File size: 2,308 Bytes
f31cfe8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import { createServer } from "http";
import { Server } from "socket.io";

const PORT = parseInt(process.env.WEBSOCKET_PORT || "3001", 10);

const httpServer = createServer((req, res) => {
  if (req.url === "/health") {
    res.writeHead(200, { "Content-Type": "application/json" });
    res.end(JSON.stringify({ status: "ok", port: PORT }));
    return;
  }
  res.writeHead(404);
  res.end();
});

const io = new Server(httpServer, {
  cors: {
    origin: process.env.NEXTAUTH_URL || "http://localhost:3000",
    methods: ["GET", "POST"],
    credentials: true,
  },
  pingTimeout: 60000,
  pingInterval: 25000,
});

interface AgentEvent {
  type: "scan_start" | "scan_complete" | "deal_found" | "deal_analyzed" | "negotiation_update" | "transaction_update" | "queue_update" | "error" | "status_change";
  data: Record<string, unknown>;
  timestamp: string;
}

const connectedClients = new Map<string, Date>();

io.on("connection", (socket) => {
  connectedClients.set(socket.id, new Date());
  console.log(`[WebSocket] Client connected: ${socket.id}`);

  socket.emit("connected", {
    clientId: socket.id,
    timestamp: new Date().toISOString(),
    serverUptime: process.uptime(),
  });

  socket.on("subscribe", (room: string) => {
    socket.join(room);
    console.log(`[WebSocket] ${socket.id} subscribed to: ${room}`);
  });

  socket.on("agent_command", (command: { action: string; payload?: unknown }) => {
    console.log(`[WebSocket] Command from ${socket.id}:`, command);
    io.emit("agent_command_ack", {
      command,
      received: new Date().toISOString(),
    });
  });

  socket.on("disconnect", () => {
    connectedClients.delete(socket.id);
    console.log(`[WebSocket] Client disconnected: ${socket.id}`);
  });
});

export function emitAgentEvent(event: AgentEvent): void {
  io.emit("agent_event", {
    ...event,
    timestamp: event.timestamp || new Date().toISOString(),
  });
}

export function emitToRoom(room: string, event: AgentEvent): void {
  io.to(room).emit("agent_event", {
    ...event,
    timestamp: event.timestamp || new Date().toISOString(),
  });
}

export function getConnectedCount(): number {
  return io.sockets.sockets.size;
}

httpServer.listen(PORT, () => {
  console.log(`[WebSocket] Server running on port ${PORT}`);
});

export { io, httpServer };