server-driven events generieren und auswerten

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
lunas
User
Beiträge: 87
Registriert: Samstag 2. Dezember 2006, 10:56

Hallo,

meine Frage hat erst einmal nicht sonderlich viel mit Python zu tun...

Ich habe ein Spiel geschrieben (in Python :-)), welches rundenbasiert abläuft. Momentan habe ich einen menschlichen und diverse Computerspieler. Der menschliche Spieler gibt seine Züge momentan per Tastatur ein. Nun möchte ich dies gerne in eine nette Browser-GUI gießen und bin schon bei meinen Vorüberlegungen auf Probleme gestoßen.

Nachdem der menschl. Spieler seinen Zug gemacht hat, spielen erst einmal die Computergegner. Dies soll natürlich im Browser angezeigt werden. Ich würde dies per Ajax machen, aber das m.E. ist Ajax client-driven, d.h. der request muss vom Browser ausgehen. Das Ereignis (Computergegner macht Zug) würde aber vom Server generiert werden und müsste einen Eventhandler im Browser triggern.

Polling möchte ich erst einmal vermeiden, aber welche Alternativen hätte ich? Den Ajax-Request einfach offen halten bis ein Event ansteht finde ich auch eher ungeschickt (ist eigentlich auch polling)... Ich habe etwas über JSON-RPC gelesen, welches über sockets anstatt HTTP läuft (die Quellen waren ein wenig mehrdeutig, also weiß ich nicht so recht ob sich damit server-driven events behandeln lassen). Könnte dies auf dem Browser laufen?

Vielleicht hat ja jemand eine elegante Lösung oder kennt ein paar Stichwörter zum googeln...

Lg,
lunas
OverNord
User
Beiträge: 72
Registriert: Donnerstag 24. Januar 2008, 11:59
Kontaktdaten:

Außer Polling sehe ich keine andere Möglichkeit. Der Server kann ja nicht einfach dem Client was senden.

HTTP läuft auch über Sockets.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

OverNord hat geschrieben:Außer Polling sehe ich keine andere Möglichkeit. Der Server kann ja nicht einfach dem Client was senden.
Doch, COMET existiert. Es ist zwar ein fuerchterlicher Hack, aber mit Divmod Nevow und Athena durchaus machbar und nicht allzu kompliziert (fuer den Entwickler).
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Neben dem Stichwort Comet kann man sich auch noch mal den zukünftigen Standard Web sockets (http://dev.w3.org/html5/websockets/) anschauen.

Und wenn's auch Java, Silverlight oder Flash sein kann, damit geht dann auch eine vom Server initiierte Kommunikation. Ansonsten hat man bei HTTP keine andere Chance als zu pollen. Man kann sich's bestenfalls mit einem Rahmenwerk webabstrahieren äh wegabstrahieren.

Stefan
lunas
User
Beiträge: 87
Registriert: Samstag 2. Dezember 2006, 10:56

Vielen Dank für die Antworten. Comet ist in etwa wonach ich gesucht habe. Aber die Installation und Nutzung von DivModNevow scheint mir ziemlich kompliziert. Später soll es mal über Apache laufen, also muss ich wohl einen anderen Weg finden...
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

lunas hat geschrieben:Später soll es mal über Apache laufen, also muss ich wohl einen anderen Weg finden...
Apache unterstützt AFAIR kein Comet, egal ob mit oder ohne Nevow. Auch nicht über Proxying.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
lunas
User
Beiträge: 87
Registriert: Samstag 2. Dezember 2006, 10:56

Das dachte ich mir schon... Dann werde ich mir etwas anderes einfallen lassen müssen.

Trotzdem danke.
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Im Rahmen meiner DA habe ich mich mit so etwas auseinander gesetzt. HTTP selbst ist erstmal clientgesteuert und zustandsbasiert. Wikipedia listet verschiedene Ansätze auf, die als Push bezeichnet werden können (dauerhaft gehaltene Verbindungen mit nach und nach gesendeten Inhalten, bis zum Erhalt von Daten aufgebaute Verbindungen gefolgt von einem neuen Request usw.). Der von sma genannte W3-Entwurf ist IIRC bisher nur in Opera implementiert und dürfte noch keine ausreichend verbreitete Basis sein. Weiterhin hat Server-Push in der Regel deutlich mehr Anforderungen auf der Seite des Servers, sei es durch zusätzliche Software (Cometd benutzt IIRC Twisted, und das ist fett und zudem ein separater Prozess) oder die Fähigkeit, sehr viele Verbindungen zeitgleich offen halten zu können. Nicht zuletzt behaupten einige Experten (Name entfallen), dass Polling nicht notwendigerweise schlechter skaliert, sondern gerade in den letzten Jahren bewiesen hat, dass es ein verlässlicher und für vieles ausreichender Ansatz ist.

Von RPC würde ich die Finger lassen. Stattdessen einfach eine URL abfragen, die Events als kompaktes JSON liefert.
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Ich muss sagen, ich kenne keine plattformübergreifende Comet-Lösung für Python, die mir gefällt. Sowohl Orbited als auch Twisted fand ich kompliziert und aufwendig zu installieren.

In Java geht das deutlich besser, da es dort der Normalfall ist, dass man einen permanent laufenden Anwendungsserver hat und nicht den Ansatz verfolgt, dass ein Programm nur zur Bearbeitung eines Requests läuft. Oder vielleicht sind das einfach die 10 Jahre Java-Programmierung in mir, die bei wirklich schwierigen Sachen nach bekannten Technologien verlangen :)

Natürlich kann man sich so einen Anwendungsserver auch in Python bauen, doch offenbar ist das dann nicht so performant. Ich habe da keine Praxiserfahrung, doch die Leute tendieren da dann ja immer dazu, in C oder anderen Sprachen etwas zu entwickeln oder Bibliotheken einzubinden. Wie etwa bei evserver (http://code.google.com/p/evserver/), der ansonsten interessant sein könnte, wenn er mal fertig wird. Java hat das nicht nötig. IMHO ein großer Vorteil.

Eine interessante Kombination könnte daher Jython in einem Jetty-Server sein, doch auch da habe ich leider (noch) keine Praxiserfahrung, von der ich berichten könnte. Versuche, Django mit Jython laufen zu lassen, waren bislang ernüchternd. Aber so langsam soll ja Jython wohl tatsächlich in Version 2.5 fertig werden.

Ansonsten: Mit Apache wird es nichts aber ich sehe auch nicht, warum ein Apache unbedingt dazwischen sein muss. Wieder erwähne ich Java, wo ein Tomcat oder Jetty (oder auch Glashfish mit Grizzly) als Server absolut ausreichend ist. Das ein Apache httpd da wirklich so viel schneller ist, ist ein hartnäckiger Mythos.

Etwas wie Twisted erfordert übrigens das Reactor-Pattern und das ist ähnlich bequem (sprich umständlich) wie continuation-passing-style (CPS) oder static-single-assignment (SSA). Erlang wäre hier eine Alternative. Oder Scala. Oder eigentlich müsste es auch etwas für Stackless Python geben.

Nicht umsonst finden die Leute von Eve-Online ja Stackless für ihren Gameserver so praktisch. Wenn man hier das Actor-Pattern (wie bei Erlang) einsetzen kann, programmiert sich auch komplexe Spielelogik gleich einfacher, kann ich mir vorstellen.

Stefan
Antworten