From 351fb8f5f7d72e6c37efd2fda4d51f1598c85175 Mon Sep 17 00:00:00 2001 From: Robert Goldmann <deadlocker@gmx.de> Date: Mon, 28 Dec 2020 13:22:39 +0100 Subject: [PATCH] added server discovery via broadcast --- settings-example.json | 6 +++++ src/StorageLeaf.py | 6 +++++ src/logic/DiscoveryService.py | 46 +++++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+) create mode 100644 src/logic/DiscoveryService.py diff --git a/settings-example.json b/settings-example.json index f831474..d98e572 100644 --- a/settings-example.json +++ b/settings-example.json @@ -22,5 +22,11 @@ "api": { "url": "http://localhost:10003", "key": "" + }, + "discovery": { + "discoveryPort": 9191, + "responsePort": 9192, + "requestMessage": "DISCOVER_STORAGELEAF_REQUEST", + "responseMessage": "DISCOVER_STORAGELEAF_RESPONSE" } } \ No newline at end of file diff --git a/src/StorageLeaf.py b/src/StorageLeaf.py index c424787..9ac70a0 100644 --- a/src/StorageLeaf.py +++ b/src/StorageLeaf.py @@ -6,6 +6,7 @@ from TheCodeLabs_FlaskUtils.FlaskBaseApp import FlaskBaseApp from blueprints import Routes, Devices, Sensors, Measurements from logic import Constants from logic.BackupService import BackupService +from logic.DiscoveryService import DiscoveryService LOGGER = DefaultLogger().create_logger_if_not_exists(Constants.APP_NAME) @@ -16,6 +17,11 @@ class StorageLeaf(FlaskBaseApp): databaseSettings = self._settings['database'] self._backupService = BackupService(databaseSettings['databasePath'], **databaseSettings['backup']) + discoverySettings = self._settings['discovery'] + discoverySettings['apiPort'] = self._settings['server']['port'] + self._discoveryService = DiscoveryService(**discoverySettings) + self._discoveryService.start() + def _register_blueprints(self, app): app.register_blueprint(Routes.construct_blueprint(self._settings, self._version)) app.register_blueprint(Devices.construct_blueprint(self._settings, self._backupService)) diff --git a/src/logic/DiscoveryService.py b/src/logic/DiscoveryService.py new file mode 100644 index 0000000..96c5eec --- /dev/null +++ b/src/logic/DiscoveryService.py @@ -0,0 +1,46 @@ +import logging +import socket +import threading + +from logic import Constants + +LOGGER = logging.getLogger(Constants.APP_NAME) + + +class DiscoveryService: + def __init__(self, discoveryPort: int, responsePort: int, requestMessage: str, responseMessage: str, apiPort: int): + self._discoveryPort = discoveryPort + self._responsePort = responsePort + self._requestMessage = requestMessage + self._responseMessage = responseMessage + self._apiPort = apiPort + + self._shouldStop = False + + def start(self): + LOGGER.debug("Start discovery thread") + + x = threading.Thread(target=self.__loop) + x.start() + + def __loop(self): + with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock: + sock.bind(('', self._discoveryPort)) + + while not self._shouldStop: + try: + data, ip = sock.recvfrom(1024) + data = data.strip() + ip = ip[0] + + if data.decode() == self._requestMessage: + LOGGER.debug(f'Received discovery request from {ip}') + with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as responseSock: + responseSock.connect((ip, self._responsePort)) + response = f'{self._responseMessage};{self._apiPort}' + responseSock.sendall(response.encode()) + except BaseException as e: + LOGGER.error(e) + + def stop(self): + self._shouldStop = True -- GitLab