@@ -124,6 +124,48 @@ const readMessage = (provider, buf, emitSynced) => {
124124 return encoder
125125}
126126
127+ /**
128+ * Outsource this function so that a new websocket connection is created immediately.
129+ * I suspect that the `ws.onclose` event is not always fired if there are network issues.
130+ *
131+ * @param {WebsocketProvider } provider
132+ * @param {WebSocket } ws
133+ */
134+ const closeWebsocketConnection = ( provider , ws ) => {
135+ if ( ws === provider . ws ) {
136+ provider . ws = null
137+ ws . close ( )
138+ provider . wsconnecting = false
139+ if ( provider . wsconnected ) {
140+ provider . wsconnected = false
141+ provider . synced = false
142+ // update awareness (all users except local left)
143+ awarenessProtocol . removeAwarenessStates (
144+ provider . awareness ,
145+ Array . from ( provider . awareness . getStates ( ) . keys ( ) ) . filter ( ( client ) =>
146+ client !== provider . doc . clientID
147+ ) ,
148+ provider
149+ )
150+ provider . emit ( 'status' , [ {
151+ status : 'disconnected'
152+ } ] )
153+ } else {
154+ provider . wsUnsuccessfulReconnects ++
155+ }
156+ // Start with no reconnect timeout and increase timeout by
157+ // using exponential backoff starting with 100ms
158+ setTimeout (
159+ setupWS ,
160+ math . min (
161+ math . pow ( 2 , provider . wsUnsuccessfulReconnects ) * 100 ,
162+ provider . maxBackoffTime
163+ ) ,
164+ provider
165+ )
166+ }
167+ }
168+
127169/**
128170 * @param {WebsocketProvider } provider
129171 */
@@ -148,35 +190,7 @@ const setupWS = (provider) => {
148190 }
149191 websocket . onclose = ( event ) => {
150192 provider . emit ( 'connection-close' , [ event , provider ] )
151- provider . ws = null
152- provider . wsconnecting = false
153- if ( provider . wsconnected ) {
154- provider . wsconnected = false
155- provider . synced = false
156- // update awareness (all users except local left)
157- awarenessProtocol . removeAwarenessStates (
158- provider . awareness ,
159- Array . from ( provider . awareness . getStates ( ) . keys ( ) ) . filter ( ( client ) =>
160- client !== provider . doc . clientID
161- ) ,
162- provider
163- )
164- provider . emit ( 'status' , [ {
165- status : 'disconnected'
166- } ] )
167- } else {
168- provider . wsUnsuccessfulReconnects ++
169- }
170- // Start with no reconnect timeout and increase timeout by
171- // using exponential backoff starting with 100ms
172- setTimeout (
173- setupWS ,
174- math . min (
175- math . pow ( 2 , provider . wsUnsuccessfulReconnects ) * 100 ,
176- provider . maxBackoffTime
177- ) ,
178- provider
179- )
193+ closeWebsocketConnection ( provider , websocket )
180194 }
181195 websocket . onopen = ( ) => {
182196 provider . wsLastMessageReceived = time . getUnixTime ( )
@@ -377,7 +391,7 @@ export class WebsocketProvider extends Observable {
377391 ) {
378392 // no message received in a long time - not even your own awareness
379393 // updates (which are updated every 15 seconds)
380- /** @type {WebSocket } */ ( this . ws ) . close ( )
394+ closeWebsocketConnection ( this , /** @type {WebSocket } */ ( this . ws ) )
381395 }
382396 } , messageReconnectTimeout / 10 ) )
383397 if ( connect ) {
@@ -484,7 +498,7 @@ export class WebsocketProvider extends Observable {
484498 this . shouldConnect = false
485499 this . disconnectBc ( )
486500 if ( this . ws !== null ) {
487- this . ws . close ( )
501+ closeWebsocketConnection ( this , this . ws )
488502 }
489503 }
490504
0 commit comments