#pragma once #include #include #include #include #include #include #include #include #include #include "ByteStream.hpp" #include "NetLibrary.hpp" typedef std::function NetClientRecvCallback; class NetClient : public std::enable_shared_from_this { public: NetClient(const std::string& serverFullID); NetClient(NetServer& server); template void send_items_to_server(const std::string& channel, Args&&... items) { if(isDisconnected) return; auto ss(std::make_shared()); { cereal::PortableBinaryOutputArchive m(*ss); (m(items), ...); } std::vector> fragmentedMessage = fragment_message(ss->view(), NetLibrary::FRAGMENT_MESSAGE_STRIDE); auto& messageQueue = messageQueues[channel]; if(fragmentedMessage.empty()) messageQueue.emplace(NetLibrary::calc_order_for_queued_message(channel, nextMessageOrderToSend), ss); else if(channel != UNRELIABLE_COMMAND_CHANNEL) { // Just drop unreliable messages that are fragmented for(auto& ss2 : fragmentedMessage) messageQueue.emplace(NetLibrary::calc_order_for_queued_message(channel, nextMessageOrderToSend), ss2); } } void update(); void add_recv_callback(MessageCommandType commandID, const NetClientRecvCallback& callback); bool is_disconnected(); std::pair get_progress_into_fragmented_message(const std::string& channel); private: std::string localID; void init_channel(const std::string& channelName, std::shared_ptr channel); void parse_received_messages(); void send_queued_messages(); void send_str_as_bytes(std::shared_ptr channel, const std::string& str); struct OutgoingMessage { MessageOrder order; std::shared_ptr ss; }; std::unordered_map> messageQueues; struct ReceiveQueue { std::mutex mut; struct ReceivedMessage { std::string channel; rtc::binary data; }; std::queue messages; }; std::shared_ptr receiveQueue; std::unordered_map> channels; std::unordered_map pfm; std::unordered_map recvCallbacks; NetServer* directConnectServer = nullptr; std::atomic isDisconnected = false; MessageOrder nextMessageOrderToSend = 0; MessageOrder nextMessageOrderToExpect = 0; std::string serverFullID; bool fullyRegistered = false; std::chrono::steady_clock::time_point lastMessageTime; friend class NetLibrary; friend class NetServer; };