A decentralized music tracking and discovery platform built on AT Protocol 🎵 rocksky.app
spotify atproto lastfm musicbrainz scrobbling listenbrainz
at main 131 lines 4.4 kB view raw
1#!/usr/bin/env -S deno run --allow-net 2 3const WS_URL = Deno.env.get("WS_URL") || "ws://localhost:2481"; 4const SLOW_MODE = Deno.env.get("SLOW_MODE") === "true"; // Set SLOW_MODE=true to slow down 5 6console.log(`🔌 Connecting to ${WS_URL}...`); 7if (SLOW_MODE) { 8 console.log(`🐌 SLOW MODE enabled - will process messages slowly`); 9} 10 11const ws = new WebSocket(WS_URL); 12 13let messageCount = 0; 14let startTime = Date.now(); 15let lastMessageTime = Date.now(); 16 17ws.onopen = () => { 18 console.log("✅ WebSocket connection opened"); 19 console.log(` readyState: ${ws.readyState}`); 20 console.log(` Time: ${new Date().toISOString()}`); 21 22 // Send ping immediately 23 console.log("📤 Sending ping..."); 24 ws.send("ping"); 25 26 // Send ping every 30 seconds (less frequent to not interfere with fast streaming) 27 setInterval(() => { 28 if (ws.readyState === WebSocket.OPEN) { 29 const now = Date.now(); 30 const timeSinceLastMessage = now - lastMessageTime; 31 console.log( 32 `📤 Sending ping... (${timeSinceLastMessage}ms since last message)`, 33 ); 34 ws.send("ping"); 35 } 36 }, 30000); 37}; 38 39ws.onmessage = async (event) => { 40 messageCount++; 41 lastMessageTime = Date.now(); 42 const elapsed = ((Date.now() - startTime) / 1000).toFixed(2); 43 44 try { 45 const data = JSON.parse(event.data); 46 47 // Handle batched messages (array of events) 48 if (Array.isArray(data)) { 49 messageCount += data.length; 50 if (messageCount % 500 === 0 || messageCount <= 50) { 51 console.log( 52 `📨 [${elapsed}s] Batch received: ${data.length} events (total: ${messageCount})`, 53 ); 54 } 55 } 56 // Handle single messages 57 else if (data.type === "connected") { 58 console.log(`📨 [${elapsed}s] Connection confirmed: ${data.message}`); 59 } else if (data.type === "heartbeat") { 60 console.log(`💓 [${elapsed}s] Heartbeat received`); 61 } else if (data.type === "error") { 62 console.log(`❌ [${elapsed}s] Error: ${data.message}`); 63 } else { 64 if (messageCount % 100 === 0 || messageCount <= 10) { 65 console.log(`📨 [${elapsed}s] Message #${messageCount}:`, data); 66 } 67 } 68 } catch { 69 // Not JSON, just log as text 70 console.log(`📨 [${elapsed}s] Message #${messageCount}: ${event.data}`); 71 } 72 73 if (messageCount % 500 === 0) { 74 const rate = (messageCount / parseFloat(elapsed)).toFixed(2); 75 console.log( 76 `📊 Progress: ${messageCount} events received in ${elapsed}s (${rate} events/s)`, 77 ); 78 } 79 80 // In slow mode, add delay to simulate slow client 81 if (SLOW_MODE && messageCount % 10 === 0) { 82 await new Promise((resolve) => setTimeout(resolve, 10)); 83 } 84}; 85 86ws.onerror = (error) => { 87 console.error("❌ WebSocket error occurred"); 88 console.error(" Error:", error); 89 console.error(" Time:", new Date().toISOString()); 90 console.error(" Messages received so far:", messageCount); 91}; 92 93ws.onclose = (event) => { 94 const elapsed = ((Date.now() - startTime) / 1000).toFixed(2); 95 const rate = 96 messageCount > 0 ? (messageCount / parseFloat(elapsed)).toFixed(2) : "0"; 97 98 console.log(`\n❌ WebSocket closed after ${elapsed}s`); 99 console.log(` Code: ${event.code}`); 100 console.log(` Reason: ${event.reason || "No reason provided"}`); 101 console.log(` Clean: ${event.wasClean}`); 102 console.log(` Total messages received: ${messageCount}`); 103 console.log(` Average rate: ${rate} messages/second`); 104 console.log(` Time: ${new Date().toISOString()}`); 105 106 if (event.code === 1006) { 107 console.error(`\n⚠️ ERROR 1006: Abnormal Closure`); 108 console.error( 109 ` This means the connection dropped without proper close frame.`, 110 ); 111 console.error(` Last message was ${Date.now() - lastMessageTime}ms ago`); 112 console.error(` Possible causes:`); 113 console.error(` - Server sent messages too fast (backpressure)`); 114 console.error(` - Server crashed or panicked`); 115 console.error(` - Network timeout or interruption`); 116 console.error(` - Client couldn't keep up with message rate`); 117 console.error( 118 `\n Try running with: SLOW_MODE=true deno run --allow-net scripts/test-client.ts`, 119 ); 120 } 121 122 Deno.exit(event.wasClean ? 0 : 1); 123}; 124 125// Handle Ctrl+C gracefully 126Deno.addSignalListener("SIGINT", () => { 127 console.log("\n🛑 Closing connection..."); 128 ws.close(); 129}); 130 131console.log("⏳ Waiting for messages... (Press Ctrl+C to exit)");