Consolen Anwendung per HTTP zur Verfügung stellen

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
nahibi
User
Beiträge: 4
Registriert: Freitag 10. Februar 2017, 14:39

Hallo,

ich habe eine c++ Consolen Anwendung welche ich mit Hilfe von Pexpect starte und steuere.
Eine Anfrage benötigt immer eine file und eine node.

Code: Alles auswählen

import pexpect

def Anfrage(child, file, node):
    child.sendline('load_solution ' + tree + '.sol')
    child.expect_exact('solution loaded')

    child.sendline('show_node ' + node)
    child.expect_exact('show_node ' + node)
    child.expect_exact('finished')

    print('result: ' + child.before)

child = pexpect.spawnu('./programm')
child.delaybeforesend = 0

Anfrage(child, 'solution1', '12345')
Eine Anfragen soll jetzt aber per http request gestellt werden können und das Ergebnis als http response zurück gesendet werden.
Wie setze ich das um? Meine Recherche hat folgendes ergeben:

Ich benötige einen HTTP Server:
Mit SimpleHTTPServer habe ich bereits einen einfachen request/response durchgeführt. Allerdings habe ich gelesen, dass man SimpleHTTPServer nur für Testzwecke verwenden soll. Welchen http Server soll ich verwenden?

Wie verbinde ich den HTTP Server mit pexpect?
Ich habe an folgendes gedacht:
- Ich starte im mainthread den HTTP Server
- in einem anderen thread starte ich via pexpect meine c++ Consolen Anwendung (die soll endlos laufen)
- wenn ein request rein kommt, löst dieser ein Event aus, welches die Anfrage Funktion (mit den passenden Variablen aus dem http request) ausführt
- das Ergebnis wird dann wieder an den mainthread übergeben und per http response zurück gesendet


Mir geht es jetzt noch nicht wirklich um den konkreten Code, sondern um eine klare Projektstruktur. Wie ist der grundsäztliche Aufbau?
Zuletzt geändert von Anonymous am Sonntag 12. Februar 2017, 10:41, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
BlackJack

@nahibi: HTTP-Server gibt's wie Sand am Meer für Python. Für diesen Einsatzzweck sollte der SimpleHTTPServer eigentlich erst einmal reichen. Allerdings wäre mir das zu kompliziert, ich würde da, je nachdem wie aufwändig die Weboberfläche wird, entweder Django oder ein Mikrorahmenwerk wie Bottle oder Flask verwenden. Mein persönlicher Favorit bei den Mikrorahmenwerken für solche Sachen ist dabei Bottle mit Jinja2 als Template-Engine.

Dort kann man auch erst einmal den integrierten Server verwenden. Der ist Singlethreaded, aber genau das wird ja auch gebraucht, denn von mehr als einem Thread kann man ja sowieso nicht auf den Prozess zugreifen.
nahibi
User
Beiträge: 4
Registriert: Freitag 10. Februar 2017, 14:39

Danke für deine Antwort. Für Django hab ich mir schon einige Tutorials angesehen und muss sagen das gefällt mir ganz gut.
Ich habe aber eine Verständnisproblem.

Ich verstehe, dass ich mit Django dynamische Webinhalte erzeugen kann.
Allerdings verstehe ich nicht, wie ich das Ergebnis meiner c++ Consolen Anwendung als dynamische Webinhalt verwenden kann.

Ich kann z.b. via CGI ein python Skript ausführen, welches meine c++ Consolen Anwendung startet, dann via pexpect Kommunikation das Ergebnis erzeug und als Webinhalt zurück liefert. Allerdings muss ich ja dann jedes mal die c++ Consolen Anwendung neu starten. Ich möchte aber meine c++ Consolen Anwendung nur einmal starten und dann für jeden request wiederverwenden.
BlackJack

@nahibi: Django war jetzt auch nur als Wahl wenn da eine umfangreichere Webseite dazu kommt. In dem Falle würde ich einen extra Server schreiben der die C++-Anwendung zur Verfügung stellt. Zum Beispiel per XML-RPC oder JSON-RPC. Oder sogar einen zusätzlichen Server mit Bottle an den die Anfragen für die C++-Anwendung dann weitergeleitet werden.
Sirius3
User
Beiträge: 17710
Registriert: Sonntag 21. Oktober 2012, 17:20

@nahibi: um die Anwendung in mehreren Requests wiederverwenden zu können, brauchst Du einen globalen Zustand und muß dafür sorgen, dass es nie zwei Requests geben kann, die gleichzeitig darauf zugreifen (Stichwort: Lock). Da Du damit schon zwei Objekte (pexpect und Lock) hast, schreibst Du am besten eine eigene Klasse, die Du erst einmal ausgiebig testest, bevor Du anfängst, darum herum einen Webservice zu schreiben.
nahibi
User
Beiträge: 4
Registriert: Freitag 10. Februar 2017, 14:39

Danke für euere Antworten.

Im moment sieht mein Konzept folgendermaßen aus:
- Website mit Django
- zusätzlichen Server mit Bottle an den die Anfragen für die C++-Anwendung weitergeleitet werden

Den Bottle Server habe ich jetzt zum laufen bekommen, allerdings noch ohne Lock.
Ich habe noch ein paar weitere Fragen:
1. Django prüft ob der Benutzer für die Anfrage an den Bottleserver autorisiert ist. Ist mein Bottleserver ausreichend von unbefugten Zugriffen geschützt, wenn ich via Firewall nur Anfragen von der Djangoserver-Ip-Adresse durchlasse?
2. Momentan verwendet der Bottleserver ja nur einen Core, wenn dieser jetzt aber mehr Cores besitzt und ich die Performance verbessern möchte, kann ich dann einfach 2xBottle+pexpect auf dem Bottleserver starten und via load-balancer abwechselend ansprechen oder macht man das dann doch mit einem multithreaded Server wie z.b. Apache?
BlackJack

@nahibi: Ohne Lock hast Du keine Probleme solange Du `bottle` nur „single threaded“ verwendest. Du kannst das mehrfach starten. Du könntest auch mehrere Threads innerhalb eines Bottle-Servers starten die jeweils einen C++-Prozess bedienen. Kommt drauf an ob der eine Thread durch den die Daten dann alle müssen, zum Flaschenhals wird oder nicht. Du kannst auch Apache/das `mod_wsgi`-Plugin das erledigen lassen und das entweder nur auf Prozesse konfigurieren oder auf Threads und Prozesse. Dann brauchst Du allerdings ein `Lock` zum Absichern. Nur Threads bringen sehr wahrscheinlich nichts, ausser das man sich das Thread-Handling im eigenen Programm spart.
nahibi
User
Beiträge: 4
Registriert: Freitag 10. Februar 2017, 14:39

Danke nochmal für die Hilfe. Habe es jetzt mit Apache + mod_wsgi gelöst.
Antworten