diff --git a/xplat/Flipper/FlipperConnectionManagerImpl.cpp b/xplat/Flipper/FlipperConnectionManagerImpl.cpp index c0f8a6259..55594368f 100644 --- a/xplat/Flipper/FlipperConnectionManagerImpl.cpp +++ b/xplat/Flipper/FlipperConnectionManagerImpl.cpp @@ -15,8 +15,8 @@ #include #include "ConnectionContextStore.h" #include "FireAndForgetBasedFlipperResponder.h" -#include "FlipperRSocket.h" #include "FlipperResponderImpl.h" +#include "FlipperSocketProvider.h" #include "FlipperStep.h" #include "Log.h" #include "yarpl/Single.h" @@ -205,7 +205,7 @@ bool FlipperConnectionManagerImpl::connectAndExchangeCertificate() { payload->sdk_version = sdkVersion; payload->medium = medium; - auto newClient = std::make_unique( + auto newClient = FlipperSocketProvider::socketCreate( endpoint, std::move(payload), connectionEventBase_); newClient->setEventHandler(ConnectionEvents(implWrapper_)); @@ -251,9 +251,26 @@ bool FlipperConnectionManagerImpl::connectSecurely() { payload->csr = contextStore_->getCertificateSigningRequest().c_str(); payload->csr_path = contextStore_->getCertificateDirectoryPath().c_str(); - auto newClient = std::make_unique( + auto newClient = FlipperSocketProvider::socketCreate( endpoint, std::move(payload), connectionEventBase_, contextStore_.get()); newClient->setEventHandler(ConnectionEvents(implWrapper_)); + /** + Message handler is only ever used for WebSocket connections. RSocket uses a + different approach whereas a responder is used instead. + */ + newClient->setMessageHandler([this](const std::string& msg) { + std::unique_ptr responder; + auto message = folly::parseJson(msg); + auto idItr = message.find("id"); + if (idItr == message.items().end()) { + responder = std::make_unique(this); + } else { + responder = std::make_unique( + this, idItr->second.getInt()); + } + + this->onMessageReceived(folly::parseJson(msg), std::move(responder)); + }); auto connectingSecurely = flipperState_->start("Connect securely"); connectionIsTrusted_ = true; diff --git a/xplat/Flipper/FlipperSocket.h b/xplat/Flipper/FlipperSocket.h index 66f9128c8..754df8311 100644 --- a/xplat/Flipper/FlipperSocket.h +++ b/xplat/Flipper/FlipperSocket.h @@ -8,7 +8,6 @@ #pragma once #include -#include #include #include #include "FlipperTransportTypes.h" @@ -26,12 +25,17 @@ class FlipperSocket { changes. @param eventHandler Observer to be notified of state changes. */ - virtual void setEventHandler(SocketEventHandler eventHandler) = 0; + virtual void setEventHandler(SocketEventHandler eventHandler) {} /** Sets the socket message handler. Used to handle received messages. + @discussion Message handler is only ever used for WebSocket connections. + RSocket uses a different approach whereas a responder is used instead. We + could create an RSocket responder that uses a message handler as well. For + simplicity, and given that RSocket will be removed in future releases, it + was decided not to follow that path. @param messageHandler Received messages handler. */ - virtual void setMessageHandler(SocketMessageHandler messageHandler) = 0; + virtual void setMessageHandler(SocketMessageHandler messageHandler) {} /** Connect the socket to the specified endpoint. This is a blocking call meaning that it will return once the socket is connected and ready to be diff --git a/xplat/Flipper/FlipperSocketProvider.cpp b/xplat/Flipper/FlipperSocketProvider.cpp new file mode 100644 index 000000000..88b6b1dd0 --- /dev/null +++ b/xplat/Flipper/FlipperSocketProvider.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include "FlipperSocketProvider.h" +#include "FlipperRSocket.h" +#include "FlipperTransportTypes.h" + +namespace facebook { +namespace flipper { + +class FlipperDefaultSocketProvider : public FlipperSocketProvider { + public: + FlipperDefaultSocketProvider() {} + virtual std::unique_ptr create( + FlipperConnectionEndpoint endpoint, + std::unique_ptr payload, + folly::EventBase* eventBase) override { + return std::make_unique( + std::move(endpoint), std::move(payload), eventBase); + } + virtual std::unique_ptr create( + FlipperConnectionEndpoint endpoint, + std::unique_ptr payload, + folly::EventBase* eventBase, + ConnectionContextStore* connectionContextStore) override { + return std::make_unique( + std::move(endpoint), + std::move(payload), + eventBase, + connectionContextStore); + } +}; + +std::unique_ptr FlipperSocketProvider::provider_ = + std::make_unique(); + +std::unique_ptr FlipperSocketProvider::socketCreate( + + FlipperConnectionEndpoint endpoint, + std::unique_ptr payload, + folly::EventBase* eventBase) { + return provider_->create(std::move(endpoint), std::move(payload), eventBase); +} + +std::unique_ptr FlipperSocketProvider::socketCreate( + FlipperConnectionEndpoint endpoint, + std::unique_ptr payload, + folly::EventBase* eventBase, + ConnectionContextStore* connectionContextStore) { + return provider_->create( + std::move(endpoint), + std::move(payload), + eventBase, + connectionContextStore); +} + +void FlipperSocketProvider::setDefaultProvider( + std::unique_ptr provider) { + provider_ = std::move(provider); +} + +} // namespace flipper +} // namespace facebook diff --git a/xplat/Flipper/FlipperSocketProvider.h b/xplat/Flipper/FlipperSocketProvider.h new file mode 100644 index 000000000..1e4e8069d --- /dev/null +++ b/xplat/Flipper/FlipperSocketProvider.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include + +namespace facebook { +namespace flipper { + +class FlipperSocket; +class FlipperConnectionManager; +class ConnectionContextStore; +struct FlipperConnectionEndpoint; +struct FlipperSocketBasePayload; + +/** + A socket provider is responsible of the creation of FlipperSocket instances. + It also defines static factory methods that can be used to construct such + instances. + */ +class FlipperSocketProvider { + public: + virtual ~FlipperSocketProvider() {} + /** + Create an instance of FlipperSocket. + @param endpoint Endpoint to connect to. + @param payload Any configuration payload to establish a connection with + the specified endpoint. + @param eventBase A folly event base used to execute connection operations. + */ + virtual std::unique_ptr create( + FlipperConnectionEndpoint endpoint, + std::unique_ptr payload, + folly::EventBase* eventBase) = 0; + /** + Create an instance of FlipperSocket. + @param endpoint Endpoint to connect to. + @param payload Any configuration payload to establish a connection with + the specified endpoint. + @param eventBase A folly event base used to execute connection operations. + @param connectionContextStore A connection context store used for obtaining + the certificate used for secure connections. + */ + virtual std::unique_ptr create( + FlipperConnectionEndpoint endpoint, + std::unique_ptr payload, + folly::EventBase* eventBase, + ConnectionContextStore* connectionContextStore) = 0; + + static std::unique_ptr socketCreate( + FlipperConnectionEndpoint endpoint, + std::unique_ptr payload, + folly::EventBase* eventBase); + static std::unique_ptr socketCreate( + FlipperConnectionEndpoint endpoint, + std::unique_ptr payload, + folly::EventBase* eventBase, + ConnectionContextStore* connectionContextStore); + + static void setDefaultProvider( + std::unique_ptr provider); + + private: + static std::unique_ptr provider_; +}; + +} // namespace flipper +} // namespace facebook