Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
U
uniset2
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
1
Issues
1
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
UniSet project repositories
uniset2
Commits
12ee9dc5
Commit
12ee9dc5
authored
Nov 20, 2021
by
Pavel Vainerman
Committed by
Pavel Vainerman
Nov 21, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[modbus slave]: supported socket reopen timeout
parent
a8ff6725
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
149 additions
and
23 deletions
+149
-23
MBSlave.cc
extensions/ModbusSlave/MBSlave.cc
+9
-0
MBSlave.h
extensions/ModbusSlave/MBSlave.h
+1
-0
ModbusTCPServer.h
include/modbus/ModbusTCPServer.h
+15
-0
ModbusTCPServer.cc
src/Communications/Modbus/ModbusTCPServer.cc
+124
-23
No files found.
extensions/ModbusSlave/MBSlave.cc
View file @
12ee9dc5
...
@@ -248,6 +248,13 @@ namespace uniset
...
@@ -248,6 +248,13 @@ namespace uniset
vmonit
(
sessTimeout
);
vmonit
(
sessTimeout
);
tmpval
=
conf
->
getArgInt
(
"--"
+
prefix
+
"-socket-timeout"
,
it
.
getProp
(
"socketTimeout"
));
if
(
tmpval
>
0
)
sockTimeout
=
tmpval
;
vmonit
(
sockTimeout
);
tmpval
=
conf
->
getArgInt
(
"--"
+
prefix
+
"-session-maxnum"
,
it
.
getProp
(
"sessMaxNum"
));
tmpval
=
conf
->
getArgInt
(
"--"
+
prefix
+
"-session-maxnum"
,
it
.
getProp
(
"sessMaxNum"
));
if
(
tmpval
>
0
)
if
(
tmpval
>
0
)
...
@@ -642,6 +649,8 @@ namespace uniset
...
@@ -642,6 +649,8 @@ namespace uniset
i
.
second
.
ptTimeout
.
reset
();
i
.
second
.
ptTimeout
.
reset
();
tcpserver
->
setMaxSessions
(
sessMaxNum
);
tcpserver
->
setMaxSessions
(
sessMaxNum
);
tcpserver
->
setSessionTimeout
(
sessTimeout
);
tcpserver
->
setSocketTimeout
(
sockTimeout
);
if
(
vaddr
.
empty
()
)
if
(
vaddr
.
empty
()
)
{
{
...
...
extensions/ModbusSlave/MBSlave.h
View file @
12ee9dc5
...
@@ -596,6 +596,7 @@ namespace uniset
...
@@ -596,6 +596,7 @@ namespace uniset
// TCPServer section..
// TCPServer section..
void
initTCPClients
(
UniXML
::
iterator
confnode
);
void
initTCPClients
(
UniXML
::
iterator
confnode
);
timeout_t
sockTimeout
=
{
UniSetTimer
::
WaitUpTime
};
/*!< таймаут на переоткрытие сокета (если нет сессий) */
timeout_t
sessTimeout
=
{
2000
};
/*!< таймаут на сессию */
timeout_t
sessTimeout
=
{
2000
};
/*!< таймаут на сессию */
timeout_t
updateStatTime
=
{
4000
};
timeout_t
updateStatTime
=
{
4000
};
ModbusTCPServer
::
Sessions
sess
;
/*!< список открытых сессий */
ModbusTCPServer
::
Sessions
sess
;
/*!< список открытых сессий */
...
...
include/modbus/ModbusTCPServer.h
View file @
12ee9dc5
...
@@ -92,6 +92,12 @@ namespace uniset
...
@@ -92,6 +92,12 @@ namespace uniset
void
setTimer
(
timeout_t
msec
);
void
setTimer
(
timeout_t
msec
);
timeout_t
getTimer
()
const
noexcept
;
timeout_t
getTimer
()
const
noexcept
;
// Таймаут для переоткрытия сокета.
// Если в течение msec миллисекунд нет действующих соединений
// сокет переоткрывается
void
setSocketTimeout
(
timeout_t
msec
);
timeout_t
getSocketTimeout
()
const
noexcept
;
protected
:
protected
:
// ожидание (при этом время отдаётся eventloop-у)
// ожидание (при этом время отдаётся eventloop-у)
...
@@ -105,6 +111,8 @@ namespace uniset
...
@@ -105,6 +111,8 @@ namespace uniset
virtual
void
ioAccept
(
ev
::
io
&
watcher
,
int
revents
);
virtual
void
ioAccept
(
ev
::
io
&
watcher
,
int
revents
);
void
onTimer
(
ev
::
timer
&
t
,
int
revents
);
void
onTimer
(
ev
::
timer
&
t
,
int
revents
);
void
onSocketTimeout
(
ev
::
timer
&
t
,
int
revents
);
void
onSocketResetTimeout
(
ev
::
async
&
watcher
,
int
revents
)
noexcept
;
void
sessionFinished
(
const
ModbusTCPSession
*
s
);
void
sessionFinished
(
const
ModbusTCPSession
*
s
);
...
@@ -145,6 +153,11 @@ namespace uniset
...
@@ -145,6 +153,11 @@ namespace uniset
ev
::
timer
ioTimer
;
ev
::
timer
ioTimer
;
std
::
shared_ptr
<
UTCPSocket
>
sock
;
std
::
shared_ptr
<
UTCPSocket
>
sock
;
ev
::
timer
sockTimeout
;
timeout_t
socketTimeout_msec
=
{
UniSetTimer
::
WaitUpTime
};
double
tmSockTimeout
=
{
0
.
0
};
ev
::
async
asyncResetSockTimeout
;
std
::
unordered_set
<
ModbusRTU
::
ModbusAddr
>
vmbaddr
;
std
::
unordered_set
<
ModbusRTU
::
ModbusAddr
>
vmbaddr
;
TimerSignal
m_timer_signal
;
TimerSignal
m_timer_signal
;
...
@@ -154,6 +167,8 @@ namespace uniset
...
@@ -154,6 +167,8 @@ namespace uniset
PassiveTimer
ptWait
;
PassiveTimer
ptWait
;
private
:
private
:
void
createSocket
();
// транслирование сигналов от Sessions..
// транслирование сигналов от Sessions..
void
postReceiveEvent
(
ModbusRTU
::
mbErrCode
res
);
void
postReceiveEvent
(
ModbusRTU
::
mbErrCode
res
);
ModbusRTU
::
mbErrCode
preReceiveEvent
(
const
std
::
unordered_set
<
ModbusRTU
::
ModbusAddr
>
vaddr
,
timeout_t
tout
);
ModbusRTU
::
mbErrCode
preReceiveEvent
(
const
std
::
unordered_set
<
ModbusRTU
::
ModbusAddr
>
vaddr
,
timeout_t
tout
);
...
...
src/Communications/Modbus/ModbusTCPServer.cc
View file @
12ee9dc5
...
@@ -46,6 +46,8 @@ namespace uniset
...
@@ -46,6 +46,8 @@ namespace uniset
io
.
set
<
ModbusTCPServer
,
&
ModbusTCPServer
::
ioAccept
>
(
this
);
io
.
set
<
ModbusTCPServer
,
&
ModbusTCPServer
::
ioAccept
>
(
this
);
ioTimer
.
set
<
ModbusTCPServer
,
&
ModbusTCPServer
::
onTimer
>
(
this
);
ioTimer
.
set
<
ModbusTCPServer
,
&
ModbusTCPServer
::
onTimer
>
(
this
);
sockTimeout
.
set
<
ModbusTCPServer
,
&
ModbusTCPServer
::
onSocketTimeout
>
(
this
);
asyncResetSockTimeout
.
set
<
ModbusTCPServer
,
&
ModbusTCPServer
::
onSocketResetTimeout
>
(
this
);
}
}
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
...
@@ -108,36 +110,50 @@ namespace uniset
...
@@ -108,36 +110,50 @@ namespace uniset
return
evIsActive
()
&&
sock
;
return
evIsActive
()
&&
sock
;
}
}
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
void
ModbusTCPServer
::
evprepare
()
void
ModbusTCPServer
::
createSocket
()
{
{
try
try
{
{
sock
=
make_shared
<
UTCPSocket
>
(
iaddr
,
port
);
auto
tmpSock
=
make_shared
<
UTCPSocket
>
(
iaddr
,
port
);
if
(
sock
)
sock
.
reset
();
sock
=
tmpSock
;
}
}
catch
(
const
Poco
::
Net
::
NetException
&
ex
)
catch
(
const
Poco
::
Net
::
NetException
&
ex
)
{
{
ostringstream
err
;
ostringstream
err
;
err
<<
"(ModbusTCPServer::
evprepare
): connect "
<<
iaddr
<<
":"
<<
port
<<
" err: "
<<
ex
.
what
();
err
<<
"(ModbusTCPServer::
createSocket
): connect "
<<
iaddr
<<
":"
<<
port
<<
" err: "
<<
ex
.
what
();
dlog
->
crit
()
<<
err
.
str
()
<<
endl
;
dlog
->
crit
()
<<
err
.
str
()
<<
endl
;
throw
uniset
::
SystemError
(
err
.
str
());
throw
uniset
::
SystemError
(
err
.
str
());
}
}
catch
(
const
std
::
exception
&
ex
)
catch
(
const
std
::
exception
&
ex
)
{
{
ostringstream
err
;
ostringstream
err
;
err
<<
"(ModbusTCPServer::evprepare
): connect "
<<
iaddr
<<
":"
<<
port
<<
" err: "
<<
ex
.
what
();
err
<<
"(ModbusTCPServer::createSocket
): connect "
<<
iaddr
<<
":"
<<
port
<<
" err: "
<<
ex
.
what
();
dlog
->
crit
()
<<
err
.
str
()
<<
endl
;
dlog
->
crit
()
<<
err
.
str
()
<<
endl
;
throw
uniset
::
SystemError
(
err
.
str
());
throw
uniset
::
SystemError
(
err
.
str
());
}
}
sock
->
setBlocking
(
false
);
sock
->
setBlocking
(
false
);
}
// -------------------------------------------------------------------------
void
ModbusTCPServer
::
evprepare
()
{
createSocket
();
io
.
set
(
loop
);
io
.
set
(
loop
);
io
.
start
(
sock
->
getSocket
(),
ev
::
READ
);
io
.
start
(
sock
->
getSocket
(),
ev
::
READ
);
ioTimer
.
set
(
loop
);
asyncResetSockTimeout
.
set
(
loop
);
asyncResetSockTimeout
.
start
();
ioTimer
.
set
(
loop
);
if
(
tmTime_msec
!=
UniSetTimer
::
WaitUpTime
)
if
(
tmTime_msec
!=
UniSetTimer
::
WaitUpTime
)
ioTimer
.
start
(
0
,
tmTime
);
ioTimer
.
start
(
0
,
tmTime
);
sockTimeout
.
set
(
loop
);
if
(
socketTimeout_msec
>
0
&&
socketTimeout_msec
!=
UniSetTimer
::
WaitUpTime
)
sockTimeout
.
start
(
0
,
tmSockTimeout
);
}
}
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
void
ModbusTCPServer
::
terminate
()
void
ModbusTCPServer
::
terminate
()
...
@@ -155,6 +171,8 @@ namespace uniset
...
@@ -155,6 +171,8 @@ namespace uniset
ioTimer
.
stop
();
ioTimer
.
stop
();
io
.
stop
();
io
.
stop
();
sockTimeout
.
stop
();
asyncResetSockTimeout
.
stop
();
auto
lst
(
slist
);
auto
lst
(
slist
);
...
@@ -183,6 +201,7 @@ namespace uniset
...
@@ -183,6 +201,7 @@ namespace uniset
{
{
slist
.
erase
(
i
);
slist
.
erase
(
i
);
sessCount
--
;
sessCount
--
;
asyncResetSockTimeout
.
send
();
return
;
return
;
}
}
}
}
...
@@ -238,7 +257,29 @@ namespace uniset
...
@@ -238,7 +257,29 @@ namespace uniset
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
timeout_t
ModbusTCPServer
::
getTimer
()
const
noexcept
timeout_t
ModbusTCPServer
::
getTimer
()
const
noexcept
{
{
return
tmTime
;
return
tmTime_msec
;
}
// -------------------------------------------------------------------------
void
ModbusTCPServer
::
setSocketTimeout
(
timeout_t
msec
)
{
socketTimeout_msec
=
msec
;
if
(
msec
==
UniSetTimer
::
WaitUpTime
||
msec
==
0
)
{
socketTimeout_msec
=
0
;
if
(
sockTimeout
.
is_active
()
)
sockTimeout
.
stop
();
}
else
{
tmSockTimeout
=
(
double
)
msec
/
1000.
;
if
(
sockTimeout
.
is_active
()
)
sockTimeout
.
start
(
0
,
tmSockTimeout
);
}
}
// ------------------------------------------------------------------------
timeout_t
ModbusTCPServer
::
getSocketTimeout
()
const
noexcept
{
return
socketTimeout_msec
;
}
}
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
void
ModbusTCPServer
::
iowait
(
timeout_t
msec
)
void
ModbusTCPServer
::
iowait
(
timeout_t
msec
)
...
@@ -286,6 +327,9 @@ namespace uniset
...
@@ -286,6 +327,9 @@ namespace uniset
connCount
++
;
connCount
++
;
if
(
sockTimeout
.
is_active
()
)
sockTimeout
.
again
();
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
)
);
...
@@ -331,26 +375,83 @@ namespace uniset
...
@@ -331,26 +375,83 @@ namespace uniset
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
void
ModbusTCPServer
::
onTimer
(
ev
::
timer
&
t
,
int
revents
)
void
ModbusTCPServer
::
onTimer
(
ev
::
timer
&
t
,
int
revents
)
{
{
if
(
EV_ERROR
&
revents
)
if
(
EV_ERROR
&
revents
)
{
{
if
(
dlog
->
is_crit
()
)
if
(
dlog
->
is_crit
()
)
dlog
->
crit
()
<<
myname
<<
"(ModbusTCPServer::ioTimer): invalid event"
<<
endl
;
dlog
->
crit
()
<<
myname
<<
"(ModbusTCPServer::ioTimer): invalid event"
<<
endl
;
return
;
}
try
{
m_timer_signal
.
emit
();
}
catch
(
std
::
exception
&
ex
)
{
if
(
dlog
->
is_crit
()
)
dlog
->
crit
()
<<
myname
<<
"(onTimer): "
<<
ex
.
what
()
<<
endl
;
}
}
// -------------------------------------------------------------------------
void
ModbusTCPServer
::
onSocketResetTimeout
(
ev
::
async
&
watcher
,
int
revents
)
noexcept
{
if
(
EV_ERROR
&
revents
)
{
if
(
dlog
->
is_crit
()
)
dlog
->
crit
()
<<
myname
<<
"(ModbusTCPServer::onSocketResetTimeout): invalid event"
<<
endl
;
return
;
return
;
}
}
try
if
(
dlog
->
is_info
()
)
{
dlog
->
info
()
<<
myname
<<
"(ModbusTCPServer::onSocketResetTimeout): reset socket timeout.."
<<
endl
;
m_timer_signal
.
emit
();
}
if
(
sockTimeout
.
is_active
()
)
catch
(
std
::
exception
&
ex
)
sockTimeout
.
again
();
{
}
if
(
dlog
->
is_crit
()
)
// -------------------------------------------------------------------------
dlog
->
crit
()
<<
myname
<<
"(onTimer): "
<<
ex
.
what
()
<<
endl
;
void
ModbusTCPServer
::
onSocketTimeout
(
ev
::
timer
&
t
,
int
revents
)
}
{
if
(
EV_ERROR
&
revents
)
{
if
(
dlog
->
is_crit
()
)
dlog
->
crit
()
<<
myname
<<
"(ModbusTCPServer::onSocketTimeout): invalid event"
<<
endl
;
return
;
}
{
std
::
lock_guard
<
std
::
mutex
>
l
(
sMutex
);
if
(
!
slist
.
empty
())
{
if
(
dlog
->
is_info
()
)
dlog
->
info
()
<<
myname
<<
"(ModbusTCPServer::onSocketTimeout): check socket [OK].."
<<
endl
;
t
.
again
();
return
;
}
}
if
(
dlog
->
is_warn
()
)
dlog
->
warn
()
<<
myname
<<
"(ModbusTCPServer::onSocketTimeout): no connections.. recreate socket.."
<<
endl
;
try
{
createSocket
();
if
(
io
.
is_active
()
)
io
.
stop
();
io
.
start
(
sock
->
getSocket
(),
ev
::
READ
);
}
catch
(
std
::
exception
&
ex
)
{
if
(
dlog
->
is_crit
()
)
dlog
->
crit
()
<<
myname
<<
"(ModbusTCPServer::onSocketTimeout): recreate socket ERROR: "
<<
ex
.
what
()
<<
endl
;
}
t
.
again
();
}
}
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
mbErrCode
ModbusTCPServer
::
realReceive
(
const
std
::
unordered_set
<
ModbusAddr
>&
vaddr
,
timeout_t
msecTimeout
)
mbErrCode
ModbusTCPServer
::
realReceive
(
const
std
::
unordered_set
<
ModbusAddr
>&
vaddr
,
timeout_t
msecTimeout
)
{
{
return
ModbusRTU
::
erOperationFailed
;
return
ModbusRTU
::
erOperationFailed
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment