@@ -4,7 +4,11 @@ import { useState, useEffect, useCallback, useRef } from 'react';
44import { Liquidation , Exchange , ExchangeConnection } from '@/types' ;
55
66const MAX_LIQUIDATIONS = 200 ;
7- const RECONNECT_DELAY = 3000 ;
7+ const RECONNECT_BASE_DELAY = 3000 ;
8+ const RECONNECT_MAX_DELAY = 60000 ;
9+ const MAX_MESSAGE_SIZE = 1024 * 1024 ; // 1MB guard against oversized payloads
10+ // Close codes that indicate we should not reconnect
11+ const NO_RECONNECT_CODES = new Set ( [ 1008 , 1011 , 4000 , 4001 , 4003 ] ) ;
812
913interface WebSocketConfig {
1014 exchange : Exchange ;
@@ -113,6 +117,9 @@ const EXCHANGES: WebSocketConfig[] = [
113117
114118 if ( valueUsd < threshold ) continue ;
115119
120+ const ts = parseInt ( liq . ts ) ;
121+ if ( ! isFinite ( ts ) ) continue ;
122+
116123 results . push ( {
117124 id : `okx-${ liq . ts } -${ liq . side } ` ,
118125 exchange : 'OKX' ,
@@ -121,7 +128,7 @@ const EXCHANGES: WebSocketConfig[] = [
121128 quantity,
122129 price,
123130 valueUsd,
124- timestamp : new Date ( parseInt ( liq . ts ) ) ,
131+ timestamp : new Date ( ts ) ,
125132 } ) ;
126133 }
127134 return results ;
@@ -239,6 +246,7 @@ export function useMultiExchangeWebSocket(threshold: number = 10000) {
239246
240247 const wsRefs = useRef < Map < Exchange , WebSocket > > ( new Map ( ) ) ;
241248 const reconnectTimeouts = useRef < Map < Exchange , NodeJS . Timeout > > ( new Map ( ) ) ;
249+ const reconnectAttempts = useRef < Map < Exchange , number > > ( new Map ( ) ) ;
242250 const thresholdRef = useRef ( threshold ) ;
243251
244252 // Keep threshold ref updated
@@ -255,13 +263,14 @@ export function useMultiExchangeWebSocket(threshold: number = 10000) {
255263 const connectExchange = useCallback (
256264 ( config : WebSocketConfig ) => {
257265 const existing = wsRefs . current . get ( config . exchange ) ;
258- if ( existing ?. readyState === WebSocket . OPEN ) return ;
266+ if ( existing ?. readyState === WebSocket . OPEN || existing ?. readyState === WebSocket . CONNECTING ) return ;
259267
260268 try {
261269 const ws = new WebSocket ( config . url ) ;
262270
263271 ws . onopen = ( ) => {
264272 console . log ( `Connected to ${ config . exchange } ` ) ;
273+ reconnectAttempts . current . set ( config . exchange , 0 ) ;
265274 updateConnection ( config . exchange , { isConnected : true , error : null } ) ;
266275
267276 if ( config . subscribe ) {
@@ -280,6 +289,7 @@ export function useMultiExchangeWebSocket(threshold: number = 10000) {
280289
281290 ws . onmessage = ( event ) => {
282291 try {
292+ if ( typeof event . data === 'string' && event . data . length > MAX_MESSAGE_SIZE ) return ;
283293 const data = JSON . parse ( event . data ) ;
284294 const incoming = config . parse ( data , thresholdRef . current ) ;
285295
@@ -300,16 +310,27 @@ export function useMultiExchangeWebSocket(threshold: number = 10000) {
300310 updateConnection ( config . exchange , { error : 'Connection error' } ) ;
301311 } ;
302312
303- ws . onclose = ( ) => {
313+ ws . onclose = ( event ) => {
304314 updateConnection ( config . exchange , { isConnected : false } ) ;
305- console . log ( `Disconnected from ${ config . exchange } , reconnecting...` ) ;
315+
316+ if ( NO_RECONNECT_CODES . has ( event . code ) ) {
317+ console . log ( `${ config . exchange } closed with code ${ event . code } , not reconnecting` ) ;
318+ updateConnection ( config . exchange , { error : `Rejected (code ${ event . code } )` } ) ;
319+ return ;
320+ }
321+
322+ const attempts = reconnectAttempts . current . get ( config . exchange ) || 0 ;
323+ const delay = Math . min ( RECONNECT_BASE_DELAY * Math . pow ( 2 , attempts ) , RECONNECT_MAX_DELAY ) ;
324+ reconnectAttempts . current . set ( config . exchange , attempts + 1 ) ;
325+
326+ console . log ( `Disconnected from ${ config . exchange } , reconnecting in ${ delay } ms...` ) ;
306327
307328 const existingTimeout = reconnectTimeouts . current . get ( config . exchange ) ;
308329 if ( existingTimeout ) clearTimeout ( existingTimeout ) ;
309330
310331 const timeout = setTimeout ( ( ) => {
311332 connectExchange ( config ) ;
312- } , RECONNECT_DELAY ) ;
333+ } , delay ) ;
313334
314335 reconnectTimeouts . current . set ( config . exchange , timeout ) ;
315336 } ;
@@ -326,6 +347,7 @@ export function useMultiExchangeWebSocket(threshold: number = 10000) {
326347 const disconnectAll = useCallback ( ( ) => {
327348 reconnectTimeouts . current . forEach ( ( timeout ) => clearTimeout ( timeout ) ) ;
328349 reconnectTimeouts . current . clear ( ) ;
350+ reconnectAttempts . current . clear ( ) ;
329351
330352 wsRefs . current . forEach ( ( ws ) => ws . close ( ) ) ;
331353 wsRefs . current . clear ( ) ;
0 commit comments