|
UniSet
2.2.1
|
00001 #ifndef UNetSender_H_ 00002 #define UNetSender_H_ 00003 // ----------------------------------------------------------------------------- 00004 #include <ostream> 00005 #include <string> 00006 #include <vector> 00007 #include <unordered_map> 00008 #include <cc++/socket.h> 00009 #include "UniSetObject.h" 00010 #include "Trigger.h" 00011 #include "Mutex.h" 00012 #include "SMInterface.h" 00013 #include "SharedMemory.h" 00014 #include "ThreadCreator.h" 00015 #include "UDPPacket.h" 00016 // ----------------------------------------------------------------------------- 00017 /* 00018 * Распределение датчиков по пакетам 00019 * ========================================================================= 00020 * Все пересылаемые данные разбиваются на группы по частоте посылки("sendfactor"). 00021 * Частота посылки кратна sendpause, задаётся для каждого датчика, при помощи свойства prefix_sendfactor. 00022 * Внутри каждой группы пакеты набираются по мере "заполнения". 00023 * 00024 * Добавление датчика в пакет и создание нового пакета при переполнении происходит в функции initItem(). 00025 * Причем так как дискретные и аналоговые датчики обрабатываются отдельно (но пересылаются в одном пакете), 00026 * то датчики, которые первые переполнятся приводят к тому, что создаётся новый пакет и они добавляются в него, 00027 * в свою очередь остальные продолжают "добивать" предыдущий пакет. 00028 * В свою очередь в initItem() каждому UItem в dlist кроме pack_ind присваивается еще и номер пакета pack_num, который гарантировано соответствует 00029 * существующему пакету, поэтому в дальнейшем при использовании pack_num в качестве ключа в mypacks мы не проверяем пакет на существование. 00030 * 00031 * ОПТИМИЗАЦИЯ N1: Для оптимизации обработки посылаемых пакетов (на стороне UNetReceiver) сделана следующая логика: 00032 * Номер очередного посылаемого пакета меняется (увеличивается) только, если изменились данные с момента 00033 последней посылки. Для этого по данным каждый раз производится расчёт UNetUDP::makeCRC() и сравнивается с последним.. 00034 */ 00035 class UNetSender 00036 { 00037 public: 00038 UNetSender( const std::string& host, const ost::tpport_t port, const std::shared_ptr<SMInterface>& smi, 00039 const std::string& s_field = "", const std::string& s_fvalue = "", const std::string& prefix = "unet", 00040 size_t maxDCount = UniSetUDP::MaxDCount, size_t maxACount = UniSetUDP::MaxACount ); 00041 00042 virtual ~UNetSender(); 00043 00044 typedef size_t sendfactor_t; 00045 00046 struct UItem 00047 { 00048 UItem(): 00049 iotype(UniversalIO::UnknownIOType), 00050 id(UniSetTypes::DefaultObjectId), 00051 pack_num(0), 00052 pack_ind(0), 00053 pack_sendfactor(0) {} 00054 00055 UniversalIO::IOType iotype; 00056 UniSetTypes::ObjectId id; 00057 IOController::IOStateList::iterator ioit; 00058 size_t pack_num; 00059 size_t pack_ind; 00060 sendfactor_t pack_sendfactor = { 0 }; 00061 00062 friend std::ostream& operator<<( std::ostream& os, UItem& p ); 00063 }; 00064 00065 typedef std::vector<UItem> DMap; 00066 00067 size_t getDataPackCount() const; 00068 00069 void start(); 00070 void stop(); 00071 00072 void send(); 00073 void real_send(UniSetUDP::UDPMessage& mypack); 00074 00076 void updateFromSM(); 00077 00079 void updateSensor( UniSetTypes::ObjectId id, long value ); 00080 00082 void updateItem( DMap::iterator& it, long value ); 00083 00084 inline void setSendPause( int msec ) 00085 { 00086 sendpause = msec; 00087 } 00088 inline void setPackSendPause( int msec ) 00089 { 00090 packsendpause = msec; 00091 } 00092 00094 void askSensors( UniversalIO::UIOCommand cmd ); 00095 00097 void initIterators(); 00098 00099 inline std::shared_ptr<DebugStream> getLog() 00100 { 00101 return unetlog; 00102 } 00103 00104 virtual const std::string getShortInfo() const; 00105 00106 inline ost::IPV4Address getAddress() const 00107 { 00108 return addr; 00109 } 00110 inline ost::tpport_t getPort() const 00111 { 00112 return port; 00113 } 00114 00115 inline size_t getADataSize() const 00116 { 00117 return maxAData; 00118 } 00119 inline size_t getDDataSize() const 00120 { 00121 return maxDData; 00122 } 00123 00124 protected: 00125 00126 std::string s_field = { "" }; 00127 std::string s_fvalue = { "" }; 00128 std::string prefix = { "" }; 00129 00130 const std::shared_ptr<SMInterface> shm; 00131 std::shared_ptr<DebugStream> unetlog; 00132 00133 bool initItem( UniXML::iterator& it ); 00134 bool readItem( const std::shared_ptr<UniXML>& xml, UniXML::iterator& it, xmlNode* sec ); 00135 00136 void readConfiguration(); 00137 00138 private: 00139 UNetSender(); 00140 00141 std::shared_ptr<ost::UDPBroadcast> udp; 00142 ost::IPV4Address addr; 00143 ost::tpport_t port = { 0 }; 00144 std::string s_host = { "" }; 00145 00146 std::string myname = { "" }; 00147 timeout_t sendpause = { 150 }; 00148 timeout_t packsendpause = { 5 }; 00149 std::atomic_bool activated = { false }; 00150 00151 UniSetTypes::uniset_rwmutex pack_mutex; 00152 00153 typedef std::unordered_map<sendfactor_t, std::vector<UniSetUDP::UDPMessage>> Packs; 00154 00155 Packs mypacks; 00156 std::unordered_map<sendfactor_t, size_t> packs_anum; 00157 std::unordered_map<sendfactor_t, size_t> packs_dnum; 00158 DMap dlist; 00159 size_t maxItem = { 0 }; 00160 size_t packetnum = { 1 }; 00161 unsigned short lastcrc = { 0 }; 00162 UniSetUDP::UDPPacket s_msg; 00163 00164 size_t maxAData = { UniSetUDP::MaxACount }; 00165 size_t maxDData = { UniSetUDP::MaxDCount }; 00166 00167 std::shared_ptr< ThreadCreator<UNetSender> > s_thr; // send thread 00168 00169 size_t ncycle = { 0 }; 00171 }; 00172 // ----------------------------------------------------------------------------- 00173 #endif // UNetSender_H_ 00174 // -----------------------------------------------------------------------------
1.7.6.1