diff --git a/settings-example.json b/settings-example.json index f831474a53409e8017fbacc11b26ad8f1057b4e6..d98e572dbc4dfe05b3bfaba7f88ddbbc59aa9495 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 c4247870deecbac020196550ed09127cf7ff3f43..9ac70a0c961e6dcb14c774666a393ac360a57976 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 0000000000000000000000000000000000000000..96c5eec96f9643619fce24f857d48b595e17de21 --- /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