Fixing client reconnection

This commit is contained in:
Artem30801
2019-04-09 10:38:35 +03:00
parent ab49fae640
commit ec05257e4e
2 changed files with 56 additions and 26 deletions

View File

@@ -27,6 +27,7 @@ logging.basicConfig( # TODO all prints as logs
class Client:
active_client = None
def __init__(self, config_path="client_config.ini"):
self.selector = selectors.DefaultSelector()
self.client_socket = None
@@ -45,6 +46,8 @@ class Client:
self.config = ConfigParser.ConfigParser()
self.load_config()
Client.active_client = self
def load_config(self):
self.config.read(self.config_path)
@@ -91,7 +94,17 @@ class Client:
unpacked = struct.unpack(NTP_PACKET_FORMAT, msg[0:struct.calcsize(NTP_PACKET_FORMAT)])
return unpacked[10] + float(unpacked[11]) / 2 ** 32 - NTP_DELTA
def reconnect(self, timeout=2, attempt_limit=5):
def start(self):
try:
while True:
self._reconnect()
self._process_connections()
except (KeyboardInterrupt, errno.EINTR):
logging.critical("Caught interrupt, exiting!")
self.selector.close()
def _reconnect(self, timeout=2, attempt_limit=5):
logging.info("Trying to connect to {}:{} ...".format(self.server_host, self.server_port))
attempt_count = 0
while not self.connected:
@@ -118,12 +131,14 @@ class Client:
self.broadcast_bind()
attempt_count = 0
def _connect(self):
self.connected = True
self.client_socket.setblocking(False)
events = selectors.EVENT_READ | selectors.EVENT_WRITE
self.selector.register(self.client_socket, events, data=self.server_connection)
self.server_connection.connect(self.selector, self.client_socket, (self.server_host, self.server_port))
self._process_connections()
def broadcast_bind(self):
@@ -149,29 +164,34 @@ class Client:
finally:
broadcast_client.close()
def mainloop(self):
try:
while True:
events = self.selector.select(timeout=1)
if events:
for key, mask in events:
if key.data is None:
pass
else:
connection = key.data
def _process_connections(self):
while True:
events = self.selector.select(timeout=1)
if events:
for key, mask in events:
if key.data is None:
pass
else:
connection = key.data
try:
connection.process_events(mask)
except Exception as error:
logging.error(
"Exception {} occurred for {}! Resetting connection!".format(error, connection.addr)
)
self.server_connection.close()
self.connected = False
break
if not self.selector.get_map():
logging.warning("No active connections left!")
#self.reconnect()
except (KeyboardInterrupt, errno.EINTR):
logging.critical("Caught interrupt, exiting!")
finally:
self.selector.close()
if not self.selector.get_map():
logging.warning("No active connections left!")
return
@messaging.request_callback("id")
def response_id():
return Client.active_client.client_id
# TODO class connection
if __name__ == "__main__":
client = Client()
client.reconnect()
client.mainloop()
client.start()

View File

@@ -130,7 +130,7 @@ class MessageManager:
self._process_content()
def message_callback(string_command):
def request_callback(string_command):
def inner(f):
ConnectionManager.requests_callbacks.update({string_command: f})
@@ -206,7 +206,6 @@ class ConnectionManager(object):
self.socket = None
def process_events(self, mask):
print(self.socket, self.selector, mask)
if mask & selectors.EVENT_READ:
self.read()
if mask & selectors.EVENT_WRITE:
@@ -262,14 +261,25 @@ class ConnectionManager(object):
def _process_message(self, message):
command = message.content["command"]
args = message.content["args"]
self.messages_callbacks[command](**args)
try:
self.messages_callbacks[command](**args)
except KeyError:
logging.warning("Command {} does not exist!".format(command))
except Exception as error:
logging.error("Error during command {} execution: {}".format(command, error))
def _process_request(self, message):
command = message.content["requested_value"]
request_id = message.content["request_id"]
args = message.content["args"]
value = self.requests_callbacks[command](**args)
self._send_response(command, request_id, value)
try:
value = self.requests_callbacks[command](**args)
except KeyError:
logging.warning("Request {} does not exist!".format(command))
except Exception as error: # TODO send response error\cancel
logging.error("Error during command {} execution: {}".format(command, error))
else:
self._send_response(command, request_id, value)
def _process_response(self, message):
request_id, requested_value = message.content["requst_id"], message.content["requested_value"]