Bottle und TCP-Server parallel verwenden

Django, Flask, Bottle, WSGI, CGI…
Antworten
pymue
User
Beiträge: 11
Registriert: Dienstag 14. Oktober 2014, 08:38

Hallo zusammen,

ich scheitere gerade an dem Versuch, das Bottle-Framework und einen TCP-Server parallel in einem Progamm zu betreiben.
Zuerst wird ein Thread erzeugt, der den TCP-Server (0.0.0.0:1756) startet; im Anschluss daran startet der Hauptthread die Bottle (localhost:8080). Der TCP-Server ist daraufhin bestens zu erreichen, Webseiten kann ich via Bottle leider nicht abrufen. Ohne TCP-Server sind auch die Webseiten wieder abrufbar.

Hat jemand evtl. schon dieses Problem gehabt und beseitigt?

Beste Grüße
BlackJack

@pymue: Ohne Code kann man dazu wohl nicht viel sagen. Minimalbeispiel wäre vielleicht nett.
pymue
User
Beiträge: 11
Registriert: Dienstag 14. Oktober 2014, 08:38

Hier mal das wesentliche zusammengestellt ...

Code: Alles auswählen

#!/usr/bin/python3.4


from System.bottle import route, run, static_file, request, abort, error
import threading
import socketserver
import queue


class ThreadedRCPRequestHandler(socketserver.BaseRequestHandler):

    def handle(self):
        data = self.request.recv(1024)
        print(data)
        self.server.setData(data)


class RCPRequestServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
    
    def __init__(self, server_address):
        socketserver.TCPServer.__init__(self, server_address, ThreadedRCPRequestHandler, bind_and_activate=True)
        self._queue = queue.Queue()
    
    def getNextMessage(self):
        return self._queue.get()
    
    def hasMessages(self):
        return not self._queue.empty()
    
    def setData(self, data):
        self._queue.put(data)
        print("valide Daten empfangen")
        
    def start(self):
        server_thread = threading.Thread(target=self.serve_forever)
        server_thread.daemon = True         # Exit the server thread when the main thread terminates
        server_thread.start()
        print("RCP Request Server running in thread: " + server_thread.name)



@route('/')
def callMyCMS():
    return "ich zeige die Messwerte"

r = RCPRequestServer(("0.0.0.0", 1756))
r.start()

run(host="localhost", port=8080, debug=False)
pymue
User
Beiträge: 11
Registriert: Dienstag 14. Oktober 2014, 08:38

irgendwie scheint das Minimalbeispiel aber zu funkionieren ... :oops:
pymue
User
Beiträge: 11
Registriert: Dienstag 14. Oktober 2014, 08:38

also der Übeltäter scheint ein weiterer thread gewesen zu sein, den ich nicht für eine kurze Zeit schlafen gelegt habe und so anscheinend den Mainthread blockiert hat.

Bin mit dem ganzen Thread-Thema noch nicht so ganz firm. Ich dachte, dass die Zeiten für Threads vom Betriebssystem zugeteilt werden. ... muss man einen Thread explizit schlafen legen, damit die anderen Threads dran kommen?
BlackJack

@pymue: Nein das sollte grundsätzlich nicht nötig sein.
pymue
User
Beiträge: 11
Registriert: Dienstag 14. Oktober 2014, 08:38

hmmm, aber in Verbindung mit Bottle scheint es wohl so zu sein. Oder mache ich noch etwas anderes falsch? Kommentiert man Zeile 30 und 31 aus, dann kann ich Ewigkeiten auf die Bottle-Ausgabe warten.

Code: Alles auswählen

#!/usr/bin/python3.4


from System.bottle import route, run
import threading
import time


class TestThread():
     
    def __init__(self):
        self._serving = False
        print("TestThread created ...")
         
    def __del__(self):
        print("TestThread destroyed ...")
        
    def start(self):
        self._serving = True
        server_thread = threading.Thread(target=self.serve)
        server_thread.daemon = True         # Exit the server thread when the main thread terminates
        server_thread.start()
        print("TestThread running in thread: " + server_thread.name)

    def stop(self):
        self._serving = False
     
    def serve(self):
        while self._serving:
            time.sleep(1)
            print("TestThread heartbeat")
#             pass
        print("TestThread stopped ...")


class cnt():
    
    def __init__(self):
        self._v = 0
    
    def inc(self):
        self._v += 1
        return self._v


c = cnt()

@route('/')
def callMyCMS():
    return "ich zeige die Messwerte " + str(c.inc())

r = TestThread()
r.start()

run(host="localhost", port=8080, debug=False)
BlackJack

@pymue: Kann ich nicht nachvollziehen. Bei mir antwortet der Webserver/Bottle auch wenn die Busy-Loop in dem anderen Thread ohne ein `sleep()` läuft.
pymue
User
Beiträge: 11
Registriert: Dienstag 14. Oktober 2014, 08:38

ich nutze python 3.4.1, bottle 0.12 als kopiertes single-file und entwickle unter windows

ich werd es in den nächsten Tagen mal unter Linux testen, aber ansonsten hab ich im Moment gar keine Idee in welcher Richtung ich suchen muss.

bin also für jeden Strohhalm dankbar.

beste Grüße

@BlackJack: besten Dank für die bisherige Hilfe
pymue
User
Beiträge: 11
Registriert: Dienstag 14. Oktober 2014, 08:38

Unter Linux läuft es wie es soll, d.h. auch ohne sleep(). Da das Endprodukt hauptsächlich auf Linux laufen soll, hat der Fehler für mich ersteinmal an Tragik verloren.

Falls jemand eine Lösung für Windows hat, lass es bitte der Nachwelt wissen.

Beste Grüße
Antworten