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