#pragma once #include "AftrConfig.h" #ifdef AFTR_CONFIG_USE_BOOST #include "NetMessengerMessageQueue.h" #include #include #include #include "NetMessengerStreamBuffer.h" #include #include #include //Written by Scott Nykl //This class deals with receiving arbitrary UDP messages that are *NOT* NetMsgs... //The user supplies a function that constructs a T or a set of Ts from the raw byte array //passed in from the network stream. namespace Aftr { template< typename T > class NetMessengerServerUDPConnT { public: using value_type = T; NetMessengerServerUDPConnT(boost::asio::io_context& io_context, std::shared_ptr< NetMessengerMessageQueueT > servListenerRecvQueue, unsigned short port, std::function< std::optional< std::vector>( uint8_t*, size_t )> createTFunc ); virtual ~NetMessengerServerUDPConnT(); boost::asio::ip::udp::socket& getSocket() { return this->udpSock; } bool isStarted() { return this->IsStarted; } void start(); //void onRecvDatagram( const boost::system::error_code& error, size_t bytesReceived ); void asyncReceiveDatagram(); std::function< std::optional< std::vector >( uint8_t*, size_t )> createTFunc; ///bool sendNetMsgSynchronousUDP( const NetMsg& msg ); //return UDP packet will goto temporary ep where datagram originated not listener socket //bool enqueueMsgToSend( NetMsg* msg ); protected: boost::asio::ip::udp::socket udpSock; boost::asio::ip::udp::endpoint ep; //one new'd each time a datagram arrives; kept until message is destroyed //static const unsigned int HEADER_LEN_BYTES = 8; ///< Header length of a message in bytes (32-bits) static constexpr unsigned int MAX_RECV_BUF_LEN = 65536; ///< Max size of a UDP Datagram static constexpr unsigned int MAX_SEND_BUF_LEN = 65536; ///< Max size of a UDP Datagram std::unique_ptr recvBuf = nullptr;///< Recv Buff of size MAX_RECV_BUF_LEN, placed on heap bool IsStarted = false; ///< Initially set to false, gets set to True once this->start() has been invoked and async operations have begun unsigned int currHeaderCode = 0; ///< Set by onRecvHeader, read by onRecvBody, indicates NetMsg subclass to instantiate unsigned int currMsgLenBytes = 0; ///< Set by onRecvHeader, read by onRecvBody, indicates length of binary data for the current message //Thread safe queue of pending messages to send to endpoint associated with this session NetMessengerMessageQueueT sendQueue; /** Pointer to corresponding NetMessengerServerListener's queue, which holds all newly received (and fully instantiated) messages until the engine processes their callbacks (NetMsg::onMessageArrived()). The callback is invoked when then engine calls NetMessengerServer::onUpdate(), which is typically in the GLView::onUpdateWorld(). This recvQueue is NOT owned by this instance, do not delete. This queue is actually owned by the corresponding NetMessengerServerListener which spawned this session's existence. */ std::weak_ptr< NetMessengerMessageQueueT > recvQueue; /// When set to 0: Continue executing asyncReceiveDatagram() on separate thread as usual. /// This will continue listening and receiving UDP data. /// When set to 1: The main thread, such as within this object's destructor, sets this value to 1. /// This signals the receiver thread to halt execution. The main thread must wait until execution /// has completed and the thread is shutting down. When the receiver thread has finished using all /// resources and is terminating with no other modifications, signalShutdownAsyncReceive is set to /// 2. /// When set to 2: The receiver thread is shutting down or terminated, but no resources will be touched /// by this thread again. std::atomic< uint8_t > signalShutdownAsyncReceive = 0; }; } //namespace Aftr #include "NetMessengerServerUDPConnT.cpptemplate.h" #endif