Skip to content

Commit 0d4b0e9

Browse files
Lukas Weberfacebook-github-bot
Lukas Weber
authored andcommitted
Fixes RCTReconnectingWebSocket connecting in infinite loop when stopped before it connects (#26864)
Summary: 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 ```objc 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
1 parent 10254a9 commit 0d4b0e9

File tree

1 file changed

+11
-2
lines changed

1 file changed

+11
-2
lines changed

Libraries/WebSocket/RCTReconnectingWebSocket.m

+11-2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ @interface RCTReconnectingWebSocket () <RCTSRWebSocketDelegate>
2020
@implementation RCTReconnectingWebSocket {
2121
NSURL *_url;
2222
RCTSRWebSocket *_socket;
23+
BOOL _stopped;
2324
}
2425

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

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

6568
- (void)reconnect
6669
{
70+
if (_stopped) {
71+
return;
72+
}
73+
6774
__weak RCTSRWebSocket *socket = _socket;
75+
__weak __typeof(self) weakSelf = self;
76+
6877
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
69-
[self start];
78+
[weakSelf start];
7079
if (!socket) {
71-
[self reconnect];
80+
[weakSelf reconnect];
7281
}
7382
});
7483
}

0 commit comments

Comments
 (0)