diff --git a/labthings/server/wsgi/gevent.py b/labthings/server/wsgi/gevent.py index fbe6f20a..8b7b2265 100644 --- a/labthings/server/wsgi/gevent.py +++ b/labthings/server/wsgi/gevent.py @@ -1,17 +1,32 @@ from geventwebsocket.handler import WebSocketHandler import gevent +import socket import logging import sys import os import signal from werkzeug.debug import DebuggedApplication +from zeroconf import IPVersion, ServiceInfo, Zeroconf, get_all_addresses + +from ..find import current_labthing + class Server: def __init__(self, app): self.app = app + # Find LabThing attached to app + self.labthing = current_labthing(app) - def run(self, host="0.0.0.0", port=5000, log=None, debug=False, stop_timeout=1): + def run( + self, + host="0.0.0.0", + port=5000, + log=None, + debug=False, + stop_timeout=1, + zeroconf=True, + ): # Type checks port = int(port) host = str(host) @@ -19,6 +34,25 @@ def run(self, host="0.0.0.0", port=5000, log=None, debug=False, stop_timeout=1): # Unmodified version of app app_to_run = self.app + # Handle zeroconf + zeroconf_server = None + if zeroconf and self.labthing: + service_info = ServiceInfo( + "_labthings._tcp.local.", + f"{self.labthing.title}._labthings._tcp.local.", + port=port, + properties={"path": self.labthing.url_prefix}, + addresses=set( + [ + socket.inet_aton(i) + for i in get_all_addresses() + if i not in ("127.0.0.1", "0.0.0.0") + ] + ), + ) + zeroconf_server = Zeroconf(ip_version=IPVersion.V4Only) + zeroconf_server.register_service(service_info) + # Handle logging if not log: log = logging.getLogger() @@ -27,7 +61,9 @@ def run(self, host="0.0.0.0", port=5000, log=None, debug=False, stop_timeout=1): if debug: log.setLevel(logging.DEBUG) app_to_run = DebuggedApplication(self.app) + logging.getLogger("zeroconf").setLevel(logging.DEBUG) + # Slightly more useful logger output friendlyhost = "localhost" if host == "0.0.0.0" else host logging.info("Starting LabThings WSGI Server") logging.info(f"Debug mode: {debug}") @@ -39,6 +75,11 @@ def run(self, host="0.0.0.0", port=5000, log=None, debug=False, stop_timeout=1): ) def stop(): + # Unregister zeroconf service + if zeroconf_server: + zeroconf_server.unregister_service(service_info) + zeroconf_server.close() + # Stop WSGI server with timeout wsgi_server.stop(timeout=stop_timeout) # Serve