Commit 7b3d01f0 authored by Pavel Vainerman's avatar Pavel Vainerman

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

и небольшой рефакторинг. Помимо этого добавил счётчик созданных соединений.
parent e77133e0
...@@ -38,11 +38,11 @@ namespace uniset ...@@ -38,11 +38,11 @@ namespace uniset
askcount_id(DefaultObjectId), askcount_id(DefaultObjectId),
respond_id(DefaultObjectId), respond_id(DefaultObjectId),
respond_invert(false), respond_invert(false),
askCount(0), connCount(0),
activated(false), activated(false),
cancelled(false), cancelled(false),
activateTimeout(500), activateTimeout(500),
pingOK(true), smPingOK(true),
force(false), force(false),
mbregFromID(false), mbregFromID(false),
prefix(prefix), prefix(prefix),
...@@ -713,6 +713,7 @@ namespace uniset ...@@ -713,6 +713,7 @@ namespace uniset
throw; throw;
} }
cerr << myname << "**************** " << endl;
msleep(tcpRepeatCreateSocketPause); msleep(tcpRepeatCreateSocketPause);
} }
...@@ -758,7 +759,7 @@ namespace uniset ...@@ -758,7 +759,7 @@ namespace uniset
{ {
try try
{ {
shm->localSetValue(itAskCount, askcount_id, askCount, getId()); shm->localSetValue(itAskCount, askcount_id, connCount, getId());
} }
catch( const uniset::Exception& ex ) catch( const uniset::Exception& ex )
{ {
...@@ -786,6 +787,11 @@ namespace uniset ...@@ -786,6 +787,11 @@ namespace uniset
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
void MBSlave::updateTCPStatistics() void MBSlave::updateTCPStatistics()
{ {
// ВНИМАНИЕ! Эта функция вызывается из основного eventLoop
// поэтому она должна быть максимально быстрой и безопасной
// иначе накроется весь обмен
// т.к. на это время останавливается работа основного потока (eventLoop)
try try
{ {
if( !tcpserver ) if( !tcpserver )
...@@ -798,15 +804,12 @@ namespace uniset ...@@ -798,15 +804,12 @@ namespace uniset
tcpserver->getSessions(sess); tcpserver->getSessions(sess);
} }
askCount = tcpserver->getAskCount(); connCount = tcpserver->getConnectionCount();
// если список сессий не пустой.. значит связь есть.. // если список сессий не пустой.. значит связь есть..
if( !sess.empty() ) if( !sess.empty() )
ptTimeout.reset(); // см. updateStatistics() ptTimeout.reset(); // см. updateStatistics()
// суммарное количество по всем
askCount = 0;
for( const auto& s : sess ) for( const auto& s : sess )
{ {
if( !activated || cancelled ) if( !activated || cancelled )
...@@ -869,10 +872,14 @@ namespace uniset ...@@ -869,10 +872,14 @@ namespace uniset
updateStatistics(); updateStatistics();
} }
catch( std::exception& ex) catch( std::exception& ex )
{ {
mbwarn << myname << "(updateStatistics): " << ex.what() << endl; mbwarn << myname << "(updateStatistics): " << ex.what() << endl;
} }
catch( ... )
{
mbwarn << myname << "(updateStatistics): unknown exception..." << endl;
}
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
void MBSlave::updateThresholds() void MBSlave::updateThresholds()
...@@ -2021,7 +2028,7 @@ namespace uniset ...@@ -2021,7 +2028,7 @@ namespace uniset
IOBase::processingAsAI( p, val, shm, force ); IOBase::processingAsAI( p, val, shm, force );
} }
*/ */
pingOK = true; smPingOK = true;
return ModbusRTU::erNoError; return ModbusRTU::erNoError;
} }
catch( uniset::NameNotFound& ex ) catch( uniset::NameNotFound& ex )
...@@ -2036,22 +2043,22 @@ namespace uniset ...@@ -2036,22 +2043,22 @@ namespace uniset
} }
catch( const uniset::Exception& ex ) catch( const uniset::Exception& ex )
{ {
if( pingOK ) if( smPingOK )
mbcrit << myname << "(real_write_prop): " << ex << endl; mbcrit << myname << "(real_write_prop): " << ex << endl;
} }
catch( const CORBA::SystemException& ex ) catch( const CORBA::SystemException& ex )
{ {
if( pingOK ) if( smPingOK )
mbcrit << myname << "(real_write_prop): СORBA::SystemException: " mbcrit << myname << "(real_write_prop): СORBA::SystemException: "
<< ex.NP_minorString() << endl; << ex.NP_minorString() << endl;
} }
catch(...) catch(...)
{ {
if( pingOK ) if( smPingOK )
mbcrit << myname << "(real_write_prop) catch ..." << endl; mbcrit << myname << "(real_write_prop) catch ..." << endl;
} }
pingOK = false; smPingOK = false;
return ModbusRTU::erTimeOut; return ModbusRTU::erTimeOut;
} }
#ifndef DISABLE_REST_API #ifndef DISABLE_REST_API
...@@ -2399,7 +2406,7 @@ namespace uniset ...@@ -2399,7 +2406,7 @@ namespace uniset
return ModbusRTU::erBadDataAddress; return ModbusRTU::erBadDataAddress;
mblog3 << myname << "(real_read_prop): read OK. sid=" << p->si.id << " val=" << val << endl; mblog3 << myname << "(real_read_prop): read OK. sid=" << p->si.id << " val=" << val << endl;
pingOK = true; smPingOK = true;
return ModbusRTU::erNoError; return ModbusRTU::erNoError;
} }
catch( uniset::NameNotFound& ex ) catch( uniset::NameNotFound& ex )
...@@ -2414,24 +2421,24 @@ namespace uniset ...@@ -2414,24 +2421,24 @@ namespace uniset
} }
catch( const uniset::Exception& ex ) catch( const uniset::Exception& ex )
{ {
if( pingOK ) if( smPingOK )
mbcrit << myname << "(real_read_prop): " << ex << endl; mbcrit << myname << "(real_read_prop): " << ex << endl;
} }
catch( const CORBA::SystemException& ex ) catch( const CORBA::SystemException& ex )
{ {
if( pingOK ) if( smPingOK )
mbcrit << myname << "(real_read_prop): CORBA::SystemException: " mbcrit << myname << "(real_read_prop): CORBA::SystemException: "
<< ex.NP_minorString() << endl; << ex.NP_minorString() << endl;
} }
catch(...) catch(...)
{ {
if( pingOK ) if( smPingOK )
mbcrit << myname << "(real_read_prop) catch ..." << endl; mbcrit << myname << "(real_read_prop) catch ..." << endl;
} }
mbwarn << myname << "(real_read_prop): read sid=" << p->si.id << " FAILED!!" << endl; mbwarn << myname << "(real_read_prop): read sid=" << p->si.id << " FAILED!!" << endl;
pingOK = false; smPingOK = false;
return ModbusRTU::erTimeOut; return ModbusRTU::erTimeOut;
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
...@@ -2538,7 +2545,7 @@ namespace uniset ...@@ -2538,7 +2545,7 @@ namespace uniset
else else
reply.setBit(0, 0, 0); reply.setBit(0, 0, 0);
pingOK = true; smPingOK = true;
return ret; return ret;
} }
...@@ -2556,7 +2563,7 @@ namespace uniset ...@@ -2556,7 +2563,7 @@ namespace uniset
bnum++; bnum++;
} }
pingOK = true; smPingOK = true;
return ModbusRTU::erNoError; return ModbusRTU::erNoError;
} }
catch( uniset::NameNotFound& ex ) catch( uniset::NameNotFound& ex )
...@@ -2566,22 +2573,22 @@ namespace uniset ...@@ -2566,22 +2573,22 @@ namespace uniset
} }
catch( const uniset::Exception& ex ) catch( const uniset::Exception& ex )
{ {
if( pingOK ) if( smPingOK )
mbcrit << myname << "(readCoilStatus): " << ex << endl; mbcrit << myname << "(readCoilStatus): " << ex << endl;
} }
catch( const CORBA::SystemException& ex ) catch( const CORBA::SystemException& ex )
{ {
if( pingOK ) if( smPingOK )
mbcrit << myname << "(readCoilStatus): СORBA::SystemException: " mbcrit << myname << "(readCoilStatus): СORBA::SystemException: "
<< ex.NP_minorString() << endl; << ex.NP_minorString() << endl;
} }
catch(...) catch(...)
{ {
if( pingOK ) if( smPingOK )
mbcrit << myname << "(readCoilStatus): catch ..." << endl; mbcrit << myname << "(readCoilStatus): catch ..." << endl;
} }
pingOK = false; smPingOK = false;
return ModbusRTU::erTimeOut; return ModbusRTU::erTimeOut;
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
...@@ -2617,7 +2624,7 @@ namespace uniset ...@@ -2617,7 +2624,7 @@ namespace uniset
else else
reply.setBit(0, 0, 0); reply.setBit(0, 0, 0);
pingOK = true; smPingOK = true;
return ret; return ret;
} }
...@@ -2635,7 +2642,7 @@ namespace uniset ...@@ -2635,7 +2642,7 @@ namespace uniset
bnum++; bnum++;
} }
pingOK = true; smPingOK = true;
return ModbusRTU::erNoError; return ModbusRTU::erNoError;
} }
catch( uniset::NameNotFound& ex ) catch( uniset::NameNotFound& ex )
...@@ -2645,22 +2652,22 @@ namespace uniset ...@@ -2645,22 +2652,22 @@ namespace uniset
} }
catch( const uniset::Exception& ex ) catch( const uniset::Exception& ex )
{ {
if( pingOK ) if( smPingOK )
mbcrit << myname << "(readInputStatus): " << ex << endl; mbcrit << myname << "(readInputStatus): " << ex << endl;
} }
catch( const CORBA::SystemException& ex ) catch( const CORBA::SystemException& ex )
{ {
if( pingOK ) if( smPingOK )
mbcrit << myname << "(readInputStatus): СORBA::SystemException: " mbcrit << myname << "(readInputStatus): СORBA::SystemException: "
<< ex.NP_minorString() << endl; << ex.NP_minorString() << endl;
} }
catch(...) catch(...)
{ {
if( pingOK ) if( smPingOK )
mbcrit << myname << "(readInputStatus): catch ..." << endl; mbcrit << myname << "(readInputStatus): catch ..." << endl;
} }
pingOK = false; smPingOK = false;
return ModbusRTU::erTimeOut; return ModbusRTU::erTimeOut;
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
...@@ -2747,7 +2754,7 @@ namespace uniset ...@@ -2747,7 +2754,7 @@ namespace uniset
if( query.subf == ModbusRTU::dgMsgSlaveCount || query.subf == ModbusRTU::dgBusMsgCount ) if( query.subf == ModbusRTU::dgMsgSlaveCount || query.subf == ModbusRTU::dgBusMsgCount )
{ {
reply = query; reply = query;
reply.data[0] = askCount; reply.data[0] = connCount;
return ModbusRTU::erNoError; return ModbusRTU::erNoError;
} }
...@@ -2832,7 +2839,7 @@ namespace uniset ...@@ -2832,7 +2839,7 @@ namespace uniset
inf << " " << ModbusRTU::addr2str(m.first) << ": iomap=" << m.second.size() << endl; inf << " " << ModbusRTU::addr2str(m.first) << ": iomap=" << m.second.size() << endl;
inf << " myaddr: " << ModbusServer::vaddr2str(vaddr) << endl; inf << " myaddr: " << ModbusServer::vaddr2str(vaddr) << endl;
inf << "Statistic: askCount=" << askCount << " pingOK=" << pingOK << endl; inf << "Statistic: connectionCount=" << connCount << " smPingOK=" << smPingOK << endl;
if( sslot ) // т.е. если у нас tcp if( sslot ) // т.е. если у нас tcp
{ {
......
...@@ -397,9 +397,9 @@ namespace uniset ...@@ -397,9 +397,9 @@ namespace uniset
friend std::ostream& operator<<( std::ostream& os, BitRegProperty* p ); friend std::ostream& operator<<( std::ostream& os, BitRegProperty* p );
}; };
inline long getAskCount() inline long getConnCount()
{ {
return askCount; return connCount;
} }
inline std::shared_ptr<LogAgregator> getLogAggregator() inline std::shared_ptr<LogAgregator> getLogAggregator()
...@@ -565,12 +565,12 @@ namespace uniset ...@@ -565,12 +565,12 @@ namespace uniset
bool respond_invert = { false }; bool respond_invert = { false };
PassiveTimer ptTimeout; PassiveTimer ptTimeout;
long askCount = { 0 }; long connCount = { 0 };
std::atomic_bool activated = { false }; std::atomic_bool activated = { false };
std::atomic_bool cancelled = { false }; std::atomic_bool cancelled = { false };
timeout_t activateTimeout = { 20000 }; // msec timeout_t activateTimeout = { 20000 }; // msec
bool pingOK = { false }; bool smPingOK = { false };
timeout_t wait_msec = { 3000 }; timeout_t wait_msec = { 3000 };
bool force = { false }; /*!< флаг означающий, что надо сохранять в SM, даже если значение не менялось */ bool force = { false }; /*!< флаг означающий, что надо сохранять в SM, даже если значение не менялось */
......
...@@ -133,14 +133,13 @@ namespace uniset ...@@ -133,14 +133,13 @@ namespace uniset
size_t getErrCount( ModbusRTU::mbErrCode e ) const; size_t getErrCount( ModbusRTU::mbErrCode e ) const;
size_t resetErrCount( ModbusRTU::mbErrCode e, size_t set = 0 ); size_t resetErrCount( ModbusRTU::mbErrCode e, size_t set = 0 );
size_t getAskCount() const; size_t getAskCount() const noexcept;
void resetAskCounter(); void resetAskCounter();
protected: protected:
virtual void iowait( timeout_t usec ); virtual void iowait( timeout_t usec );
/*! реализация получения очередного сообщения */ /*! реализация получения очередного сообщения */
virtual ModbusRTU::mbErrCode realReceive( const std::unordered_set<ModbusRTU::ModbusAddr>& vaddr, timeout_t msecTimeout ) = 0; virtual ModbusRTU::mbErrCode realReceive( const std::unordered_set<ModbusRTU::ModbusAddr>& vaddr, timeout_t msecTimeout ) = 0;
......
...@@ -51,17 +51,17 @@ namespace uniset ...@@ -51,17 +51,17 @@ namespace uniset
virtual bool isActive() const override; virtual bool isActive() const override;
void setMaxSessions( size_t num ); void setMaxSessions( size_t num );
size_t getMaxSessions() const; size_t getMaxSessions() const noexcept;
/*! установить timeout для поддержания соединения с "клиентом" (Default: 10 сек) */ /*! установить timeout для поддержания соединения с "клиентом" (Default: 10 сек) */
void setSessionTimeout( timeout_t msec ); void setSessionTimeout( timeout_t msec );
timeout_t getSessionTimeout() const; timeout_t getSessionTimeout() const noexcept;
/*! текущее количество подключений */ /*! текущее количество подключений */
size_t getCountSessions() const; size_t getCountSessions() const noexcept;
void setIgnoreAddrMode( bool st ); void setIgnoreAddrMode( bool st );
bool getIgnoreAddrMode() const; bool getIgnoreAddrMode() const noexcept;
// Сбор статистики по соединениям... // Сбор статистики по соединениям...
struct SessionInfo struct SessionInfo
...@@ -76,8 +76,11 @@ namespace uniset ...@@ -76,8 +76,11 @@ namespace uniset
void getSessions( Sessions& lst ); void getSessions( Sessions& lst );
std::string getInetAddress() const; std::string getInetAddress() const noexcept;
int getInetPort() const; int getInetPort() const noexcept;
// статистика
size_t getConnectionCount() const noexcept;
// ------------------------------------------------- // -------------------------------------------------
// Таймер. // Таймер.
...@@ -90,7 +93,7 @@ namespace uniset ...@@ -90,7 +93,7 @@ namespace uniset
TimerSignal signal_timer(); TimerSignal signal_timer();
void setTimer( timeout_t msec ); void setTimer( timeout_t msec );
inline timeout_t getTimer() const; timeout_t getTimer() const noexcept;
protected: protected:
...@@ -136,6 +139,9 @@ namespace uniset ...@@ -136,6 +139,9 @@ namespace uniset
size_t maxSessions = { 100 }; size_t maxSessions = { 100 };
size_t sessCount = { 0 }; size_t sessCount = { 0 };
// Статистика
size_t connCount = { 0 }; // количество обработанных соединений
timeout_t sessTimeout = { 10000 }; // msec timeout_t sessTimeout = { 10000 }; // msec
ev::io io; ev::io io;
......
...@@ -57,10 +57,10 @@ namespace uniset ...@@ -57,10 +57,10 @@ namespace uniset
virtual bool isActive() const override; virtual bool isActive() const override;
void iowait( timeout_t msec );
protected: protected:
virtual void iowait( timeout_t msec ) override;
virtual ModbusRTU::mbErrCode realReceive( const std::unordered_set<ModbusRTU::ModbusAddr>& vmbaddr, timeout_t msecTimeout ) override; virtual ModbusRTU::mbErrCode realReceive( const std::unordered_set<ModbusRTU::ModbusAddr>& vmbaddr, timeout_t msecTimeout ) override;
void callback( ev::io& watcher, int revents ); void callback( ev::io& watcher, int revents );
......
...@@ -1732,7 +1732,7 @@ namespace uniset ...@@ -1732,7 +1732,7 @@ namespace uniset
return ret; return ret;
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
size_t ModbusServer::getAskCount() const size_t ModbusServer::getAskCount() const noexcept
{ {
return askCount; return askCount;
} }
......
...@@ -71,12 +71,12 @@ namespace uniset ...@@ -71,12 +71,12 @@ namespace uniset
maxSessions = num; maxSessions = num;
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
size_t ModbusTCPServer::getMaxSessions() const size_t ModbusTCPServer::getMaxSessions() const noexcept
{ {
return maxSessions; return maxSessions;
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
size_t ModbusTCPServer::getCountSessions() const size_t ModbusTCPServer::getCountSessions() const noexcept
{ {
return sessCount; return sessCount;
} }
...@@ -86,7 +86,7 @@ namespace uniset ...@@ -86,7 +86,7 @@ namespace uniset
ignoreAddr = st; ignoreAddr = st;
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
bool ModbusTCPServer::getIgnoreAddrMode() const bool ModbusTCPServer::getIgnoreAddrMode() const noexcept
{ {
return ignoreAddr; return ignoreAddr;
} }
...@@ -96,7 +96,7 @@ namespace uniset ...@@ -96,7 +96,7 @@ namespace uniset
sessTimeout = msec; sessTimeout = msec;
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
timeout_t ModbusTCPServer::getSessionTimeout() const timeout_t ModbusTCPServer::getSessionTimeout() const noexcept
{ {
return sessTimeout; return sessTimeout;
} }
...@@ -147,7 +147,7 @@ namespace uniset ...@@ -147,7 +147,7 @@ namespace uniset
ioTimer.set(loop); ioTimer.set(loop);
if( tmTime_msec != UniSetTimer::WaitUpTime ) if( tmTime_msec != UniSetTimer::WaitUpTime )
ioTimer.start(tmTime); ioTimer.start(0,tmTime);
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
void ModbusTCPServer::terminate() void ModbusTCPServer::terminate()
...@@ -171,7 +171,8 @@ namespace uniset ...@@ -171,7 +171,8 @@ namespace uniset
// Копируем сперва себе список сессий.. // Копируем сперва себе список сессий..
// т.к при вызове terminate() // т.к при вызове terminate()
// у Session будет вызван сигнал "final" // у Session будет вызван сигнал "final"
// который приведёт к вызову sessionFinished()..в котором список будет меняться.. // который приведёт к вызову sessionFinished()..
// в котором этот список будет меняться (удалится сессия из списка)
for( const auto& s : lst ) for( const auto& s : lst )
{ {
try try
...@@ -202,22 +203,24 @@ namespace uniset ...@@ -202,22 +203,24 @@ namespace uniset
std::lock_guard<std::mutex> l(sMutex); std::lock_guard<std::mutex> l(sMutex);
for( const auto& i : slist ) for( const auto& i : slist )
{ lst.emplace_back( i->getClientAddress(), i->getAskCount() );
SessionInfo inf( i->getClientAddress(), i->getAskCount() );
lst.emplace_back( std::move(inf) );
}
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
string ModbusTCPServer::getInetAddress() const string ModbusTCPServer::getInetAddress() const noexcept
{ {
return iaddr; return iaddr;
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
int ModbusTCPServer::getInetPort() const int ModbusTCPServer::getInetPort() const noexcept
{ {
return port; return port;
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
size_t ModbusTCPServer::getConnectionCount() const noexcept
{
return connCount;
}
// -------------------------------------------------------------------------
ModbusTCPServer::TimerSignal ModbusTCPServer::signal_timer() ModbusTCPServer::TimerSignal ModbusTCPServer::signal_timer()
{ {
return m_timer_signal; return m_timer_signal;
...@@ -239,11 +242,11 @@ namespace uniset ...@@ -239,11 +242,11 @@ namespace uniset
tmTime = (double)msec / 1000.; tmTime = (double)msec / 1000.;
if( ioTimer.is_active() ) if( ioTimer.is_active() )
ioTimer.start( tmTime ); ioTimer.start( 0, tmTime );
} }
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
timeout_t ModbusTCPServer::getTimer() const timeout_t ModbusTCPServer::getTimer() const noexcept
{ {
return tmTime; return tmTime;
} }
...@@ -291,6 +294,8 @@ namespace uniset ...@@ -291,6 +294,8 @@ namespace uniset
{ {
Poco::Net::StreamSocket ss = sock->acceptConnection(); Poco::Net::StreamSocket ss = sock->acceptConnection();
connCount++;
auto s = make_shared<ModbusTCPSession>(ss, *vmbaddr, sessTimeout); auto s = make_shared<ModbusTCPSession>(ss, *vmbaddr, sessTimeout);
s->connectReadCoil( sigc::mem_fun(this, &ModbusTCPServer::readCoilStatus) ); s->connectReadCoil( sigc::mem_fun(this, &ModbusTCPServer::readCoilStatus) );
s->connectReadInputStatus( sigc::mem_fun(this, &ModbusTCPServer::readInputStatus) ); s->connectReadInputStatus( sigc::mem_fun(this, &ModbusTCPServer::readInputStatus) );
...@@ -327,10 +332,10 @@ namespace uniset ...@@ -327,10 +332,10 @@ namespace uniset
s->run(loop); s->run(loop);
sessCount++; sessCount++;
} }
catch( Exception& ex ) catch( std::exception& ex )
{ {
if( dlog->is_crit() ) if( dlog->is_crit() )
dlog->crit() << myname << "(ModbusTCPServer): new connection error: " << ex << endl; dlog->crit() << myname << "(ModbusTCPServer): new connection error: " << ex.what() << endl;
} }
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
......
...@@ -110,6 +110,10 @@ namespace uniset ...@@ -110,6 +110,10 @@ namespace uniset
{ {
cerr << "(EventLoopServer::defaultLoop): " << ex.what() << endl; cerr << "(EventLoopServer::defaultLoop): " << ex.what() << endl;
} }
catch( ... )
{
cerr << "(EventLoopServer::defaultLoop): UNKNOWN EXCEPTION.." << endl;
}
isrunning = false; isrunning = false;
looprunOK_event.notify_all(); looprunOK_event.notify_all();
......
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