1*3f982cf4SFabien Sanglard // Copyright 2020 The Chromium Authors. All rights reserved. 2*3f982cf4SFabien Sanglard // Use of this source code is governed by a BSD-style license that can be 3*3f982cf4SFabien Sanglard // found in the LICENSE file. 4*3f982cf4SFabien Sanglard 5*3f982cf4SFabien Sanglard #ifndef CAST_STREAMING_SESSION_MESSENGER_H_ 6*3f982cf4SFabien Sanglard #define CAST_STREAMING_SESSION_MESSENGER_H_ 7*3f982cf4SFabien Sanglard 8*3f982cf4SFabien Sanglard #include <functional> 9*3f982cf4SFabien Sanglard #include <string> 10*3f982cf4SFabien Sanglard #include <utility> 11*3f982cf4SFabien Sanglard #include <vector> 12*3f982cf4SFabien Sanglard 13*3f982cf4SFabien Sanglard #include "absl/types/optional.h" 14*3f982cf4SFabien Sanglard #include "absl/types/variant.h" 15*3f982cf4SFabien Sanglard #include "cast/common/public/message_port.h" 16*3f982cf4SFabien Sanglard #include "cast/streaming/answer_messages.h" 17*3f982cf4SFabien Sanglard #include "cast/streaming/offer_messages.h" 18*3f982cf4SFabien Sanglard #include "cast/streaming/receiver_message.h" 19*3f982cf4SFabien Sanglard #include "cast/streaming/sender_message.h" 20*3f982cf4SFabien Sanglard #include "json/value.h" 21*3f982cf4SFabien Sanglard #include "platform/api/task_runner.h" 22*3f982cf4SFabien Sanglard #include "util/flat_map.h" 23*3f982cf4SFabien Sanglard #include "util/weak_ptr.h" 24*3f982cf4SFabien Sanglard 25*3f982cf4SFabien Sanglard namespace openscreen { 26*3f982cf4SFabien Sanglard namespace cast { 27*3f982cf4SFabien Sanglard 28*3f982cf4SFabien Sanglard // A message port interface designed specifically for use by the Receiver 29*3f982cf4SFabien Sanglard // and Sender session classes. 30*3f982cf4SFabien Sanglard class SessionMessenger : public MessagePort::Client { 31*3f982cf4SFabien Sanglard public: 32*3f982cf4SFabien Sanglard using ErrorCallback = std::function<void(Error)>; 33*3f982cf4SFabien Sanglard 34*3f982cf4SFabien Sanglard SessionMessenger(MessagePort* message_port, 35*3f982cf4SFabien Sanglard std::string source_id, 36*3f982cf4SFabien Sanglard ErrorCallback cb); 37*3f982cf4SFabien Sanglard ~SessionMessenger() override; 38*3f982cf4SFabien Sanglard 39*3f982cf4SFabien Sanglard protected: 40*3f982cf4SFabien Sanglard // Barebones message sending method shared by both children. 41*3f982cf4SFabien Sanglard [[nodiscard]] Error SendMessage(const std::string& destination_id, 42*3f982cf4SFabien Sanglard const std::string& namespace_, 43*3f982cf4SFabien Sanglard const Json::Value& message_root); 44*3f982cf4SFabien Sanglard 45*3f982cf4SFabien Sanglard // Used to report errors in subclasses. 46*3f982cf4SFabien Sanglard void ReportError(Error error); 47*3f982cf4SFabien Sanglard 48*3f982cf4SFabien Sanglard private: 49*3f982cf4SFabien Sanglard MessagePort* const message_port_; 50*3f982cf4SFabien Sanglard ErrorCallback error_callback_; 51*3f982cf4SFabien Sanglard }; 52*3f982cf4SFabien Sanglard 53*3f982cf4SFabien Sanglard class SenderSessionMessenger final : public SessionMessenger { 54*3f982cf4SFabien Sanglard public: 55*3f982cf4SFabien Sanglard using ReplyCallback = std::function<void(ReceiverMessage)>; 56*3f982cf4SFabien Sanglard 57*3f982cf4SFabien Sanglard SenderSessionMessenger(MessagePort* message_port, 58*3f982cf4SFabien Sanglard std::string source_id, 59*3f982cf4SFabien Sanglard std::string receiver_id, 60*3f982cf4SFabien Sanglard ErrorCallback cb, 61*3f982cf4SFabien Sanglard TaskRunner* task_runner); 62*3f982cf4SFabien Sanglard 63*3f982cf4SFabien Sanglard // Set receiver message handler. Note that this should only be 64*3f982cf4SFabien Sanglard // applied for messages that don't have sequence numbers, like RPC 65*3f982cf4SFabien Sanglard // and status messages. 66*3f982cf4SFabien Sanglard void SetHandler(ReceiverMessage::Type type, ReplyCallback cb); 67*3f982cf4SFabien Sanglard 68*3f982cf4SFabien Sanglard // Send a request (with optional reply callback). 69*3f982cf4SFabien Sanglard [[nodiscard]] Error SendOutboundMessage(SenderMessage message); 70*3f982cf4SFabien Sanglard [[nodiscard]] Error SendRequest(SenderMessage message, 71*3f982cf4SFabien Sanglard ReceiverMessage::Type reply_type, 72*3f982cf4SFabien Sanglard ReplyCallback cb); 73*3f982cf4SFabien Sanglard 74*3f982cf4SFabien Sanglard // MessagePort::Client overrides 75*3f982cf4SFabien Sanglard void OnMessage(const std::string& source_id, 76*3f982cf4SFabien Sanglard const std::string& message_namespace, 77*3f982cf4SFabien Sanglard const std::string& message) override; 78*3f982cf4SFabien Sanglard void OnError(Error error) override; 79*3f982cf4SFabien Sanglard 80*3f982cf4SFabien Sanglard private: 81*3f982cf4SFabien Sanglard TaskRunner* const task_runner_; 82*3f982cf4SFabien Sanglard 83*3f982cf4SFabien Sanglard // This messenger should only be connected to one receiver, so |receiver_id_| 84*3f982cf4SFabien Sanglard // should not change. 85*3f982cf4SFabien Sanglard const std::string receiver_id_; 86*3f982cf4SFabien Sanglard 87*3f982cf4SFabien Sanglard // We keep a list here of replies we are expecting--if the reply is 88*3f982cf4SFabien Sanglard // received for this sequence number, we call its respective callback, 89*3f982cf4SFabien Sanglard // otherwise it is called after an internally specified timeout. 90*3f982cf4SFabien Sanglard FlatMap<int, ReplyCallback> awaiting_replies_; 91*3f982cf4SFabien Sanglard 92*3f982cf4SFabien Sanglard // Currently we can only set a handler for RPC messages, so no need for 93*3f982cf4SFabien Sanglard // a flatmap here. 94*3f982cf4SFabien Sanglard ReplyCallback rpc_callback_; 95*3f982cf4SFabien Sanglard 96*3f982cf4SFabien Sanglard WeakPtrFactory<SenderSessionMessenger> weak_factory_{this}; 97*3f982cf4SFabien Sanglard }; 98*3f982cf4SFabien Sanglard 99*3f982cf4SFabien Sanglard class ReceiverSessionMessenger final : public SessionMessenger { 100*3f982cf4SFabien Sanglard public: 101*3f982cf4SFabien Sanglard using RequestCallback = std::function<void(SenderMessage)>; 102*3f982cf4SFabien Sanglard ReceiverSessionMessenger(MessagePort* message_port, 103*3f982cf4SFabien Sanglard std::string source_id, 104*3f982cf4SFabien Sanglard ErrorCallback cb); 105*3f982cf4SFabien Sanglard 106*3f982cf4SFabien Sanglard // Set sender message handler. 107*3f982cf4SFabien Sanglard void SetHandler(SenderMessage::Type type, RequestCallback cb); 108*3f982cf4SFabien Sanglard 109*3f982cf4SFabien Sanglard // Send a JSON message. 110*3f982cf4SFabien Sanglard [[nodiscard]] Error SendMessage(ReceiverMessage message); 111*3f982cf4SFabien Sanglard 112*3f982cf4SFabien Sanglard // MessagePort::Client overrides 113*3f982cf4SFabien Sanglard void OnMessage(const std::string& source_id, 114*3f982cf4SFabien Sanglard const std::string& message_namespace, 115*3f982cf4SFabien Sanglard const std::string& message) override; 116*3f982cf4SFabien Sanglard void OnError(Error error) override; 117*3f982cf4SFabien Sanglard 118*3f982cf4SFabien Sanglard private: 119*3f982cf4SFabien Sanglard // The sender ID of the SenderSession we are connected to. Set on the 120*3f982cf4SFabien Sanglard // first message we receive. 121*3f982cf4SFabien Sanglard std::string sender_session_id_; 122*3f982cf4SFabien Sanglard FlatMap<SenderMessage::Type, RequestCallback> callbacks_; 123*3f982cf4SFabien Sanglard }; 124*3f982cf4SFabien Sanglard 125*3f982cf4SFabien Sanglard } // namespace cast 126*3f982cf4SFabien Sanglard } // namespace openscreen 127*3f982cf4SFabien Sanglard 128*3f982cf4SFabien Sanglard #endif // CAST_STREAMING_SESSION_MESSENGER_H_ 129