Skip to content

Commit 9710fe3

Browse files
committed
#149 SerialServer could be stopped when running on a thread
1 parent 26e2468 commit 9710fe3

File tree

1 file changed

+23
-36
lines changed

1 file changed

+23
-36
lines changed

pymodbus/server/sync.py

Lines changed: 23 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515
from pymodbus.device import ModbusDeviceIdentification
1616
from pymodbus.transaction import *
1717
from pymodbus.exceptions import NotImplementedException, NoSuchSlaveException
18-
from pymodbus.exceptions import ModbusIOException
19-
from pymodbus.exceptions import InvalidMessageRecievedException
2018
from pymodbus.pdu import ModbusExceptions as merror
2119
from pymodbus.compat import socketserver, byte2int
2220

@@ -30,6 +28,7 @@
3028
#---------------------------------------------------------------------------#
3129
# Protocol Handlers
3230
#---------------------------------------------------------------------------#
31+
3332
class ModbusBaseRequestHandler(socketserver.BaseRequestHandler):
3433
''' Implements the modbus server protocol
3534
@@ -87,34 +86,6 @@ def send(self, message):
8786
raise NotImplementedException("Method not implemented by derived class")
8887

8988

90-
# class ModbusSingleRequestHandler(ModbusBaseRequestHandler):
91-
# ''' Implements the modbus server protocol
92-
#
93-
# This uses the socketserver.BaseRequestHandler to implement
94-
# the client handler for a single client(serial clients)
95-
# '''
96-
#
97-
# def handle(self):
98-
# ''' Callback when we receive any data
99-
# '''
100-
# while self.running:
101-
# try:
102-
# data = self.request.recv(1024)
103-
# if data:
104-
# if _logger.isEnabledFor(logging.DEBUG):
105-
# _logger.debug(' '.join([hex(byte2int(x)) for x in data]))
106-
# self.framer.processIncomingPacket(data, self.execute)
107-
# except Exception as msg:
108-
# # since we only have a single socket, we cannot exit
109-
# _logger.error("Socket error occurred %s" % msg)
110-
#
111-
# def send(self, message):
112-
# ''' Send a request (string) to the network
113-
#
114-
# :param message: The unencoded modbus response
115-
# '''
116-
117-
11889
class ModbusSingleRequestHandler(ModbusBaseRequestHandler):
11990
''' Implements the modbus server protocol
12091
@@ -138,7 +109,6 @@ def handle(self):
138109
self.framer.resetFrame()
139110
_logger.error("Socket error occurred %s" % msg)
140111

141-
142112
def send(self, message):
143113
''' Send a request (string) to the network
144114
@@ -152,6 +122,16 @@ def send(self, message):
152122
return self.request.send(pdu)
153123

154124

125+
class CustomSingleRequestHandler(ModbusSingleRequestHandler):
126+
127+
def __init__(self, request, client_address, server):
128+
self.request = request
129+
self.client_address = client_address
130+
self.server = server
131+
self.running = True
132+
self.setup()
133+
134+
155135
class ModbusConnectedRequestHandler(ModbusBaseRequestHandler):
156136
''' Implements the modbus server protocol
157137
@@ -389,6 +369,8 @@ class ModbusSerialServer(object):
389369
server context instance.
390370
'''
391371

372+
handler = None
373+
392374
def __init__(self, context, framer=None, identity=None, **kwargs):
393375
''' Overloaded initializer for the socket server
394376
@@ -425,6 +407,7 @@ def __init__(self, context, framer=None, identity=None, **kwargs):
425407
self.socket = None
426408
self._connect()
427409
self.is_running = True
410+
self._build_handler()
428411

429412
def _connect(self):
430413
''' Connect to the serial server
@@ -449,9 +432,9 @@ def _build_handler(self):
449432
request = self.socket
450433
request.send = request.write
451434
request.recv = request.read
452-
handler = ModbusSingleRequestHandler(request,
453-
(self.device, self.device), self)
454-
return handler
435+
self.handler = CustomSingleRequestHandler(request,
436+
(self.device, self.device),
437+
self)
455438

456439
def serve_forever(self):
457440
''' Callback for connecting a new client thread
@@ -460,15 +443,19 @@ def serve_forever(self):
460443
:param client: The address of the client
461444
'''
462445
_logger.debug("Started thread to serve client")
463-
handler = self._build_handler()
446+
if not self.handler:
447+
self._build_handler()
464448
while self.is_running:
465-
handler.handle()
449+
self.handler.handle()
466450

467451
def server_close(self):
468452
''' Callback for stopping the running server
469453
'''
470454
_logger.debug("Modbus server stopped")
471455
self.is_running = False
456+
self.handler.finish()
457+
self.handler.running = False
458+
self.handler = None
472459
self.socket.close()
473460

474461

0 commit comments

Comments
 (0)