1 /*** 2 This file is part of snapcast 3 Copyright (C) 2014-2021 Johannes Pohl 4 5 This program is free software: you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation, either version 3 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program. If not, see <http://www.gnu.org/licenses/>. 17 ***/ 18 19 #ifndef STREAM_SERVER_HPP 20 #define STREAM_SERVER_HPP 21 22 #include <boost/asio.hpp> 23 #include <memory> 24 #include <mutex> 25 #include <set> 26 #include <sstream> 27 #include <vector> 28 29 #include "common/queue.h" 30 #include "common/sample_format.hpp" 31 #include "control_server.hpp" 32 #include "jsonrpcpp.hpp" 33 #include "message/codec_header.hpp" 34 #include "message/message.hpp" 35 #include "message/server_settings.hpp" 36 #include "server_settings.hpp" 37 #include "stream_session.hpp" 38 #include "streamreader/stream_manager.hpp" 39 40 using namespace streamreader; 41 42 using boost::asio::ip::tcp; 43 using acceptor_ptr = std::unique_ptr<tcp::acceptor>; 44 using session_ptr = std::shared_ptr<StreamSession>; 45 46 47 /// Forwars PCM data to the connected clients 48 /** 49 * Reads PCM data using PipeStream, implements PcmListener to get the (encoded) PCM stream. 50 * Accepts and holds client connections (StreamSession) 51 * Receives (via the StreamMessageReceiver interface) and answers messages from the clients 52 * Forwards PCM data to the clients 53 */ 54 class StreamServer : public StreamMessageReceiver 55 { 56 public: 57 StreamServer(boost::asio::io_context& io_context, const ServerSettings& serverSettings, StreamMessageReceiver* messageReceiver = nullptr); 58 virtual ~StreamServer(); 59 60 void start(); 61 void stop(); 62 63 /// Send a message to all connceted clients 64 // void send(const msg::BaseMessage* message); 65 66 void addSession(const std::shared_ptr<StreamSession>& session); 67 void onMetaChanged(const PcmStream* pcmStream, std::shared_ptr<msg::StreamTags> meta); 68 void onChunkEncoded(const PcmStream* pcmStream, bool isDefaultStream, std::shared_ptr<msg::PcmChunk> chunk, double duration); 69 70 session_ptr getStreamSession(const std::string& clientId) const; 71 session_ptr getStreamSession(StreamSession* session) const; 72 73 private: 74 void startAccept(); 75 void handleAccept(tcp::socket socket); 76 void cleanup(); 77 78 /// Implementation of StreamMessageReceiver 79 void onMessageReceived(StreamSession* streamSession, const msg::BaseMessage& baseMessage, char* buffer) override; 80 void onDisconnect(StreamSession* streamSession) override; 81 82 mutable std::recursive_mutex sessionsMutex_; 83 mutable std::recursive_mutex clientMutex_; 84 std::vector<std::weak_ptr<StreamSession>> sessions_; 85 boost::asio::io_context& io_context_; 86 std::vector<acceptor_ptr> acceptor_; 87 boost::asio::steady_timer config_timer_; 88 89 ServerSettings settings_; 90 Queue<std::shared_ptr<msg::BaseMessage>> messages_; 91 StreamMessageReceiver* messageReceiver_; 92 }; 93 94 95 96 #endif 97