Commit 0b926265 authored by Pavel Vainerman's avatar Pavel Vainerman

(ModbusMultiSlave): добавил настройки основных параметров,

статистические датчики, help
parent 4aad5897
......@@ -12,7 +12,8 @@ using namespace UniSetExtensions;
using namespace ModbusRTU;
// -----------------------------------------------------------------------------
MBTCPMultiSlave::MBTCPMultiSlave( UniSetTypes::ObjectId objId, UniSetTypes::ObjectId shmId, SharedMemory* ic, const string& prefix ):
MBSlave(objId,shmId,ic,prefix)
MBSlave(objId,shmId,ic,prefix),
sesscount_id(DefaultObjectId)
{
cnode = conf->getNode(myname);
if( cnode == NULL )
......@@ -24,6 +25,16 @@ MBSlave(objId,shmId,ic,prefix)
if( waitTimeout == 0 )
waitTimeout = 4000;
sessTimeout = conf->getArgInt("--" + prefix + "-session-timeout",it.getProp("sessTimeout"));
if( sessTimeout == 0 )
sessTimeout = 10000;
sessMaxNum = conf->getArgInt("--" + prefix + "-session-maxnum",it.getProp("sessMaxNum"));
if( sessMaxNum == 0 )
sessMaxNum = 10;
sesscount_id = conf->getSensorID( conf->getArgParam("--" + prefix + "-session-count-id",it.getProp("sesscount")) );
UniXML::iterator cit(it);
if( cit.find("clients") && cit.goChildren() )
......@@ -89,6 +100,12 @@ MBTCPMultiSlave::~MBTCPMultiSlave()
void MBTCPMultiSlave::help_print( int argc, const char* const* argv )
{
MBSlave::help_print(argc,argv);
cerr << endl;
cout << "--prefix-wait-timeout msec - Время ожидания очередного соединения и обновление статистики работы. По умолчанию: 4 сек." << endl;
cout << "--prefix-session-timeout msec - Таймаут на закрытие соединения с 'клиентом', если от него нет запросов. По умолчанию: 10 сек." << endl;
cout << "--prefix-session-maxnum num - Маскимальное количество соединений. По умолчанию: 10." << endl;
cout << "--prefix-session-count-id id - Датчик для отслеживания текущего количества соединений." << endl;
}
// -----------------------------------------------------------------------------
MBTCPMultiSlave* MBTCPMultiSlave::init_mbslave( int argc, const char* const* argv, UniSetTypes::ObjectId icID, SharedMemory* ic,
......@@ -131,6 +148,8 @@ void MBTCPMultiSlave::execute_tcp()
for( auto &i: cmap )
i.second.ptTimeout.reset();
sslot->setMaxSessions( sessMaxNum );
while(1)
{
try
......@@ -142,7 +161,6 @@ void MBTCPMultiSlave::execute_tcp()
sslot->getSessions(sess);
for( auto& s: sess )
{
cerr << " find " << s.iaddr << endl;
auto i = cmap.find( s.iaddr );
if( i!=cmap.end() )
{
......@@ -253,6 +271,18 @@ void MBTCPMultiSlave::execute_tcp()
dcrit << myname << "(execute_rtu): (askCount) " << ex << std::endl;
}
}
if( sesscount_id!=DefaultObjectId )
{
try
{
shm->localSetValue(sesscount_it,sesscount_id, sslot->getCountSessions(),getId());
}
catch(Exception& ex)
{
dcrit << myname << "(execute_rtu): (sessCount) " << ex << std::endl;
}
}
}
catch(...){}
}
......@@ -261,6 +291,9 @@ void MBTCPMultiSlave::execute_tcp()
void MBTCPMultiSlave::initIterators()
{
MBSlave::initIterators();
shm->initIterator(sesscount_it);
for( auto &i: cmap )
i.second.initIterators(shm);
}
......
......@@ -7,7 +7,7 @@
#include "modbus/ModbusTCPServer.h"
// -----------------------------------------------------------------------------
/*!
<MBTCPMultiSlave ....>
<MBTCPMultiSlave ....sesscount="">
<clients>
<item ip="" respond="" invert="1" askcount=""/>
<item ip="" respond="" invert="1" askcount=""/>
......@@ -36,8 +36,10 @@ class MBTCPMultiSlave:
virtual void execute_tcp() override;
virtual void initIterators() override;
timeout_t sessTimeout; /*!< таймаут на сессию */
timeout_t waitTimeout;
ModbusTCPServer::Sessions sess; /*!< список открытых сессий */
unsigned int sessMaxNum;
struct ClientInfo
{
......@@ -65,6 +67,10 @@ class MBTCPMultiSlave:
typedef std::map<const std::string,ClientInfo> ClientsMap;
ClientsMap cmap;
UniSetTypes::ObjectId sesscount_id;
IOController::IOStateList::iterator sesscount_it;
};
// -----------------------------------------------------------------------------
#endif // _MBTCPMultiSlave_H_
......
......@@ -35,6 +35,10 @@ class ModbusTCPServer:
void setMaxSessions( unsigned int num );
inline unsigned int getMaxSessions(){ return maxSessions; }
/*! установить timeout для поддержания соединения с "клиентом" (Default: 10 сек) */
void setSessionTimeout( timeout_t msec );
inline timeout_t getSessionTimeout(){ return sessTimeout; }
/*! текущее количество подключений */
unsigned getCountSessions();
......@@ -87,6 +91,8 @@ class ModbusTCPServer:
unsigned int maxSessions;
unsigned int sessCount;
timeout_t sessTimeout;
private:
};
......
......@@ -16,7 +16,7 @@ class ModbusTCPSession:
{
public:
ModbusTCPSession( ost::TCPSocket &server, ModbusRTU::ModbusAddr mbaddr );
ModbusTCPSession( ost::TCPSocket &server, ModbusRTU::ModbusAddr mbaddr, timeout_t timeout );
virtual ~ModbusTCPSession();
void cleanInputStream();
......@@ -93,6 +93,7 @@ class ModbusTCPSession:
ModbusTCP::MBAPHeader curQueryHeader;
ModbusRTU::ModbusAddr addr;
PassiveTimer ptTimeout;
timeout_t timeout;
ModbusRTU::ModbusMessage buf;
bool ignoreAddr;
......
......@@ -13,7 +13,8 @@ ModbusTCPServer::ModbusTCPServer( ost::InetAddress &ia, int port ):
iaddr(ia),
ignoreAddr(false),
maxSessions(10),
sessCount(0)
sessCount(0),
sessTimeout(10000)
{
setCRCNoCheckit(true);
}
......@@ -47,22 +48,24 @@ unsigned ModbusTCPServer::getCountSessions()
return sessCount;
}
// -------------------------------------------------------------------------
void ModbusTCPServer::setSessionTimeout( timeout_t msec )
{
sessTimeout = msec;
}
// -------------------------------------------------------------------------
bool ModbusTCPServer::waitQuery( ModbusRTU::ModbusAddr mbaddr, timeout_t msec )
{
if( msec == 0 )
msec = UniSetTimer::WaitUpTime;
cerr << "*** sessCount=" << sessCount << " maxSess=" << maxSessions << endl;
if( sessCount >= maxSessions )
return false;
try
{
cerr << "*** wait connection: " << msec << " msec" << endl;
if( isPendingConnection(msec) )
{
ModbusTCPSession* s = new ModbusTCPSession(*this,mbaddr);
ModbusTCPSession* s = new ModbusTCPSession(*this,mbaddr,sessTimeout);
s->connectReadCoil( sigc::mem_fun(this, &ModbusTCPServer::readCoilStatus) );
s->connectReadInputStatus( sigc::mem_fun(this, &ModbusTCPServer::readInputStatus) );
......@@ -114,8 +117,8 @@ mbErrCode ModbusTCPServer::receive( ModbusRTU::ModbusAddr addr, timeout_t timeou
ModbusMessage buf;
mbErrCode res = erTimeOut;
// Thread::setException(Thread::throwException);
//#warning "Why timeout can be 0 there?"
// Thread::setException(Thread::throwException);
// #warning "Why timeout can be 0 there?"
assert(timeout);
ptTimeout.reset();
......
......@@ -16,9 +16,10 @@ ModbusTCPSession::~ModbusTCPSession()
{
}
// -------------------------------------------------------------------------
ModbusTCPSession::ModbusTCPSession( ost::TCPSocket &server, ModbusRTU::ModbusAddr a ):
ModbusTCPSession::ModbusTCPSession( ost::TCPSocket &server, ModbusRTU::ModbusAddr a, timeout_t timeout ):
TCPSession(server),
addr(a),
timeout(timeout),
peername(""),
caddr(""),
askCount(0)
......@@ -34,12 +35,6 @@ unsigned int ModbusTCPSession::getAskCount()
// -------------------------------------------------------------------------
void ModbusTCPSession::run()
{
#warning DEBUG PARAM!!
timeout_t msec = 10000; // для отладки..
PassiveTimer ptTimeout(msec);
ModbusMessage buf;
{
ost::tpport_t p;
ost::InetAddress iaddr = getIPV4Peer(&p);
......@@ -50,14 +45,16 @@ void ModbusTCPSession::run()
ostringstream s;
s << iaddr << ":" << p;
peername = s.str();
// struct in_addr a = iaddr.getAddress();
// cerr << "**************** CREATE SESS FOR " << string( inet_ntoa(a) ) << endl;
}
ModbusRTU::mbErrCode res = erTimeOut;
while( isPending(Socket::pendingInput, msec) )
while( isPending(Socket::pendingInput, timeout) )
{
res = receive(addr,msec);
res = receive(addr,timeout);
// cerr << peername << ": query result=" << res << endl;
if( res == erSessionClosed )
break;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment