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

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

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