@@ -40,7 +40,7 @@ import { info as refCacheInfo } from "@cocalc/util/refcache";
40
40
import { connect as connectToConat } from "@cocalc/conat/core/client" ;
41
41
import type { ConnectionStats } from "@cocalc/conat/core/types" ;
42
42
import { appBasePath } from "@cocalc/frontend/customize/app-base-path" ;
43
- import { once } from "@cocalc/util/async-utils" ;
43
+ import { once , until } from "@cocalc/util/async-utils" ;
44
44
import { delay } from "awaiting" ;
45
45
import {
46
46
deleteRememberMe ,
@@ -95,6 +95,10 @@ export class ConatClient extends EventEmitter {
95
95
this . _conatClient = connectToConat ( {
96
96
address,
97
97
inboxPrefix : inboxPrefix ( { account_id : this . client . account_id } ) ,
98
+ // it is necessary to manually managed reconnects due to a bugs
99
+ // in socketio that has stumped their devs
100
+ // -- https://github.com/socketio/socket.io/issues/5197
101
+ reconnection : false ,
98
102
} ) ;
99
103
this . _conatClient . on ( "connected" , ( ) => {
100
104
this . setConnectionStatus ( {
@@ -113,6 +117,7 @@ export class ConatClient extends EventEmitter {
113
117
stats : this . _conatClient ?. stats ,
114
118
} ) ;
115
119
this . client . emit ( "disconnected" , "offline" ) ;
120
+ setTimeout ( this . connect , 1000 ) ;
116
121
} ) ;
117
122
this . _conatClient . conn . io . on ( "reconnect_attempt" , ( attempt ) => {
118
123
this . numConnectionAttempts = attempt ;
@@ -226,15 +231,38 @@ export class ConatClient extends EventEmitter {
226
231
227
232
// if there is a connection, resume it
228
233
resume = ( ) => {
229
- if ( this . permanentlyDisconnected ) {
230
- console . log (
231
- "Not connecting -- client is permanently disconnected and must refresh their browser" ,
232
- ) ;
233
- return ;
234
- }
235
- this . _conatClient ?. conn . io . connect ( ) ;
234
+ this . connect ( ) ;
236
235
} ;
237
236
237
+ // keep trying until connected.
238
+ connect = reuseInFlight ( async ( ) => {
239
+ let attempts = 0 ;
240
+ await until (
241
+ async ( ) => {
242
+ if ( this . permanentlyDisconnected ) {
243
+ console . log (
244
+ "Not connecting -- client is permanently disconnected and must refresh their browser" ,
245
+ ) ;
246
+ return true ;
247
+ }
248
+ if ( this . _conatClient == null ) {
249
+ this . conat ( ) ;
250
+ }
251
+ if ( this . _conatClient ?. conn ?. connected ) {
252
+ return true ;
253
+ }
254
+ await waitForOnline ( ) ;
255
+ attempts += 1 ;
256
+ console . log (
257
+ `Connecting to ${ this . _conatClient ?. options . address } : attempts ${ attempts } ` ,
258
+ ) ;
259
+ this . _conatClient ?. conn . io . connect ( ) ;
260
+ return false ;
261
+ } ,
262
+ { min : 3000 , max : 15000 } ,
263
+ ) ;
264
+ } ) ;
265
+
238
266
callConatService : CallConatServiceFunction = async ( options ) => {
239
267
return await callConatService ( options ) ;
240
268
} ;
@@ -498,3 +526,14 @@ function setNotDeleted({ project_id, path }) {
498
526
const actions = redux . getProjectActions ( project_id ) ;
499
527
actions ?. setRecentlyDeleted ( path , 0 ) ;
500
528
}
529
+
530
+ async function waitForOnline ( ) : Promise < void > {
531
+ if ( navigator . onLine ) return ;
532
+ await new Promise < void > ( ( resolve ) => {
533
+ const handler = ( ) => {
534
+ window . removeEventListener ( "online" , handler ) ;
535
+ resolve ( ) ;
536
+ } ;
537
+ window . addEventListener ( "online" , handler ) ;
538
+ } ) ;
539
+ }
0 commit comments