Skip to content
Browse files
Fixes RCTReconnectingWebSocket connecting in infinite loop when stopp…
…ed before it connects (#26864)

When `[RCTReconnectingWebSocket stop]` is called and `[RCTReconnectingWebSocket  reconnect]` is scheduled afterwards (i.e. connection didn't happen before `[RCTReconnectingWebSocket stop]` being invoked), it will keep reconnecting forever.

Also fixes retain loop in block within `[RCTReconnectingWebSocket  reconnect]`. When RCTReconnectingWebSocket is stopped and reference to it set to nil, block in reconnect will still keep self alive and reconnecting forever.

I found this edge case when I tried to stop RCTPackagerConnection after some time, so it doesn't spam with `[] nw_socket_handle_socket_event [C34585.1:1] Socket SO_ERROR [61: Connection refused]` when we don' have Metro running (we have brownfield app, so iOS devs don't need Metro running most of the time).

## Changelog
[iOS] [Fixed] -  RCTReconnectingWebSocket is reconnecting infinitely when stopped before getting connected
Pull Request resolved: #26864

Test Plan:
- Put breakpoint into `[RCTReconnectingWebSocket  reconnect]`
- Start sample RN app **without having Metro running**
- Into AppDelegate add something like
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
   [RCTPackagerConnection.sharedPackagerConnection stop]
- After the previous block is dispatched reconnect should not be invoked anymore

Reviewed By: motiz88

Differential Revision: D19767742

Pulled By: rickhanlonii

fbshipit-source-id: dabb2369b06217b961e9d2611257c106d350f70c
  • Loading branch information
Lukas Weber authored and facebook-github-bot committed Feb 11, 2020
1 parent 10254a9 commit 0d4b0e941725657d8e63940428888aaceff505ad
Showing 1 changed file with 11 additions and 2 deletions.
@@ -20,6 +20,7 @@ @interface RCTReconnectingWebSocket () <RCTSRWebSocketDelegate>
@implementation RCTReconnectingWebSocket {
NSURL *_url;
RCTSRWebSocket *_socket;
BOOL _stopped;

- (instancetype)initWithURL:(NSURL *)url queue:(dispatch_queue_t)queue
@@ -44,6 +45,7 @@ - (void)send:(id)data
- (void)start
[self stop];
_stopped = NO;
_socket = [[RCTSRWebSocket alloc] initWithURL:_url];
_socket.delegate = self;
[_socket setDelegateDispatchQueue:_delegateDispatchQueue];
@@ -52,6 +54,7 @@ - (void)start

- (void)stop
_stopped = YES;
_socket.delegate = nil;
[_socket closeWithCode:1000 reason:@"Invalidated"];
_socket = nil;
@@ -64,11 +67,17 @@ - (void)webSocket:(RCTSRWebSocket *)webSocket didReceiveMessage:(id)message

- (void)reconnect
if (_stopped) {

__weak RCTSRWebSocket *socket = _socket;
__weak __typeof(self) weakSelf = self;

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self start];
[weakSelf start];
if (!socket) {
[self reconnect];
[weakSelf reconnect];

0 comments on commit 0d4b0e9

Please sign in to comment.