diff --git a/packages/react-native/React/Inspector/RCTCxxInspectorPackagerConnectionDelegate.mm b/packages/react-native/React/Inspector/RCTCxxInspectorPackagerConnectionDelegate.mm index d6fb7b32d11..b7bf705b289 100644 --- a/packages/react-native/React/Inspector/RCTCxxInspectorPackagerConnectionDelegate.mm +++ b/packages/react-native/React/Inspector/RCTCxxInspectorPackagerConnectionDelegate.mm @@ -32,6 +32,9 @@ std::unique_ptr RCTCxxInspectorPackagerConnectionDelegate::connectWe std::weak_ptr delegate) { auto *adapter = [[RCTCxxInspectorWebSocketAdapter alloc] initWithURL:url delegate:delegate]; + if (!adapter) { + return nullptr; + } return std::make_unique(adapter); } diff --git a/packages/react-native/React/Inspector/RCTCxxInspectorWebSocketAdapter.mm b/packages/react-native/React/Inspector/RCTCxxInspectorWebSocketAdapter.mm index a7a2fcbd9f7..1535020e1bb 100644 --- a/packages/react-native/React/Inspector/RCTCxxInspectorWebSocketAdapter.mm +++ b/packages/react-native/React/Inspector/RCTCxxInspectorWebSocketAdapter.mm @@ -19,6 +19,8 @@ using namespace facebook::react::jsinspector_modern; +static const uint64_t MAX_CONNECTING_TIME_NS = 2 * 1000000000L; + namespace { NSString *NSStringFromUTF8StringView(std::string_view view) { @@ -39,6 +41,15 @@ NSString *NSStringFromUTF8StringView(std::string_view view) _webSocket = [[SRWebSocket alloc] initWithURL:[NSURL URLWithString:NSStringFromUTF8StringView(url)]]; _webSocket.delegate = self; [_webSocket open]; + uint64_t startTime = clock_gettime_nsec_np(CLOCK_MONOTONIC_RAW); + while ([_webSocket readyState] == SR_CONNECTING) { + if ((clock_gettime_nsec_np(CLOCK_MONOTONIC_RAW) - startTime) > MAX_CONNECTING_TIME_NS) { + break; + } + } + if ([_webSocket readyState] != SR_OPEN) { + return nil; + } } return self; } diff --git a/packages/react-native/ReactCommon/jsinspector-modern/InspectorPackagerConnection.cpp b/packages/react-native/ReactCommon/jsinspector-modern/InspectorPackagerConnection.cpp index 6c0d2875d80..edbe59a73c2 100644 --- a/packages/react-native/ReactCommon/jsinspector-modern/InspectorPackagerConnection.cpp +++ b/packages/react-native/ReactCommon/jsinspector-modern/InspectorPackagerConnection.cpp @@ -180,7 +180,7 @@ void InspectorPackagerConnection::Impl::didFailWithError( if (webSocket_) { abort(posixCode, "WebSocket exception", error); } - if (!closed_ && posixCode != ECONNREFUSED) { + if (!closed_) { reconnect(); } } @@ -249,6 +249,10 @@ void InspectorPackagerConnection::Impl::reconnect() { if (strongSelf && !strongSelf->closed_) { strongSelf->reconnectPending_ = false; strongSelf->connect(); + + if (!strongSelf->isConnected()) { + strongSelf->reconnect(); + } } }, RECONNECT_DELAY); diff --git a/packages/react-native/ReactCommon/jsinspector-modern/tests/InspectorPackagerConnectionTest.cpp b/packages/react-native/ReactCommon/jsinspector-modern/tests/InspectorPackagerConnectionTest.cpp index a4c59d9735d..0823d66beee 100644 --- a/packages/react-native/ReactCommon/jsinspector-modern/tests/InspectorPackagerConnectionTest.cpp +++ b/packages/react-native/ReactCommon/jsinspector-modern/tests/InspectorPackagerConnectionTest.cpp @@ -846,17 +846,6 @@ TEST_F(InspectorPackagerConnectionTest, TestReconnectOnSocketErrorWithNoCode) { packagerConnection_->closeQuietly(); } -TEST_F(InspectorPackagerConnectionTest, TestNoReconnectOnConnectionRefused) { - // Configure gmock to expect calls in a specific order. - InSequence mockCallsMustBeInSequence; - - packagerConnection_->connect(); - ASSERT_TRUE(webSockets_[0]); - webSockets_[0]->getDelegate().didFailWithError(ECONNREFUSED, "Test error"); - EXPECT_FALSE(webSockets_[0]); - EXPECT_FALSE(packagerConnection_->isConnected()); -} - TEST_F(InspectorPackagerConnectionTest, TestUnknownEvent) { packagerConnection_->connect(); ASSERT_TRUE(webSockets_[0]);