2010-10-27 5 views
10

Wir haben eine Website und haben dafür ein Chat-System entwickelt, das die strophe.js-Bibliothek und den ejabberd XMPP-Server verwendet. Wir verwenden Session-Attachment, das mit PHP initiiert wurde (unter Verwendung einer internen Bibliothek). Was wir tun, ist die RID und SID aus dem PHP-Skript zu bekommen, dann verwenden Sie den Session-Anhang von strophe. Die genannte RID und SID werden in einem Cookie gespeichert und der RID-Wert auf dem Cookie wird bei jeder Aktualisierung der RID auf strophe.js aktualisiert. (Dies ist so, dass wir die Sitzungs-ID bei der Seitenaktualisierung/Navigation zu anderen Stellen auf der Site wiederverwenden können)XMPP Web Chat: Wie löst man mehrere Tabs/Fenster auf?

Wir planen nun, dass es auf mehreren Tabs/Windows funktioniert. Ich habe die Facebook-Implementierung beobachtet, und für jede Registerkarte gibt es eine lange Abfrageanforderung an eine bestimmte Domäne. Diese Domäne ist für jede Registerkarte unterschiedlich. Zum Beispiel wäre Tab 1 0.86.channel.facebook.com. Die zweite Registerkarte wäre 1.86.channel.facebook.com. Wie ich verstehe, ist dies die Browser-Beschränkung von 2 aktiven Anfragen auf eine bestimmte Domain zu lösen. Wie wird diese Multi-Domain-Lösung implementiert?

Als nächstes wäre auf den Chat-Sitzungen selbst. Die Chat-Sitzungen wären je nach Tab unterschiedlich, oder? Wie würde die Benutzeroberfläche mit jedem Tab wie Facebook synchronisiert? Meine Idee ist, dass bei jeder Aktion eine Nachricht an die eigene JID des Benutzers gesendet wird, die die mit dem Chat verbundene Aktion enthält. Zum Beispiel würde ein Chat-Fenster zu öffnen eine Nachricht Strophe wie folgt senden:

<message from="my_own_jid" to="my_own_jid" type="chat"> 
    <body>{"jid-of-contact":"open-chat-box"}</body> 
</message> 

und dies würde auf dem Chat-Client und die Benutzeroberfläche angepasst würde entsprechend (in diesem Fall aufgefangen werden, eine Chat-Box für eine Kontaktöffnung).

Irgendwelche Vorschläge/Kommentare zu dieser Implementierung?

Danke!

+0

Bei Multi-Domain: Eine andere Domain könnte einfach eine Weiterleitung von Anfragen von verschiedenen Domains an den von ihnen verwendeten XMPP-Server sein. Es könnte nur eine "Verkleidung" auf der Seite des Browsers sein. In Bezug darauf, wie man sich unter einem einzigen Benutzernamen an derselben Ressource anmeldet, hmm, ich frage mich, ob FB den XMPP-Server implementiert/modifiziert hat, den sie verwenden, um dies zu erreichen. Es wäre interessant zu wissen. – DashK

+0

Zur Pflege des Benutzeroberflächen-Erscheinungsbilds auf mehreren Registerkarten: Ich frage mich, ob Sie den Datenspeicher von HTML5 verwenden können, um den "Status" des Chats beizubehalten, und jede Registerkarte nur ... auf Aktualisierungen im Datenspeicher reagiert? Gemäß den XMPP-Spezifikationen sollten Sie in der Lage sein, die Ressourcenpriorität zu verwenden, um zu "steuern", wohin Nachrichtenzeilenzeilen gesendet werden. Frage mich, ob du das nutzen kannst, um deinen Mehrfach-Tab-Effekt zu erreichen ... – DashK

+0

@DashKAre loggen sie sich auf derselben Ressource ein? Ich denke, es ist eine andere Sitzung und jeder mit einer anderen Ressource. Auf diese Weise muss der XMPP-Server nicht geändert werden (und mehrere Anmeldungen für denselben Benutzer mit derselben Ressource sind gegen den XMPP-Standard, richtig?). – putolaruan

Antwort

8

Ich und mein Team arbeiteten an genau dem gleichen Problem - nur dass wir Openfire anstelle von Ejabberd verwenden (hauptsächlich weil wir Java-Fähigkeiten haben, aber Erlang nicht kennen). Unsere Firma baut Browsergames.

Unsere Lösung besteht aus:

  • XMPPHP - für Prebinding
  • Strophe.js - für die Sitzungs Befestigung ( modifiziert)
  • Punjab - als Connection Manager (erweitert, modifiziert)
  • Openfire - als XMPP-Server

Wir verwenden Punjab, weil die BOSH-Implementierung von Openfire mit den anderen Komponenten zunächst nicht sehr gut zu funktionieren scheint.

Grundsätzlich haben wir entschieden, keine Sitzung für jede Registerkarte zu erstellen. Dies liegt an der Tatsache, dass einige unserer Spiele so funktionieren, wie es bei gewöhnlichen Websites der Fall ist: Ein Klick auf einen Link fordert eine komplette neue Seite an (während die neueren Spiele voll in ajax funktionieren und der größte Teil der GUI gleich bleibt). Mit anderen Worten: Unser webbasierter Chat muss in Umgebungen arbeiten, in denen sich der Benutzer über die Website bewegt. Eine Sitzung für eine Registerkarte würde für jede Seitenanforderung eine neue Sitzung bedeuten, die wie ein großer Aufwand erscheint, da die Spieler oft ziemlich schnell klicken. Also - wir wollten eine Sitzung erstellen und bei einem Spieler bleiben.

Um das zu lösen, haben wir - wie Sie - strophe.js geändert, um die RID in einem Cookie zu lesen/speichern, so dass alle Registerkarten die aktuelle RID kennen und auf einen korrekten Wert erhöhen. Eine andere Sache ist, wir haben Strophe eine CID zum Körper der XMPP-Strophen hinzufügen lassen. CID wie Client-ID. Ich werde die Verwendung bald erklären.

Als nächstes war der Plan, zwei Dinge in Punjab zu ändern. Zuerst haben wir eine Klasse hinzugefügt, die die übliche Art und Weise ersetzt, in der wartende Anfragen in Punjab gespeichert werden. Wartende BOSH-Anfragen werden nun in einem Wörterbuch gespeichert, wobei die CID (die strophe.js jetzt dem Hauptteil jeder Anfrage hinzufügt) als Schlüssel verwendet wird. Wenn eine andere Anfrage von der gleichen Registerkarte ankommt, dann weiß punjab, auf welche Wartungsanfrage eine leere Antwort gesendet werden soll. Wenn neue Strophen ausgeliefert werden sollen, sendet punjab diese an alle wartenden Anfragen im Wörterbuch. So wird eine eingehende Nachricht an alle Registerkarten verteilt. Zweitens haben wir ein paar Zeilen hinzugefügt, so dass eine Nachricht, die von einem Tab gesendet wurde, sofort an alle anderen Tabs zurückgeschickt wird. Die Nachricht kann also auch in den anderen Tabs angezeigt werden.

Natürlich gibt es andere Probleme, die auftreten müssen, wie zum Beispiel den Chatverlauf in der GUI nicht zu verlieren, wenn der Spieler zum nächsten Bildschirm weitergeht. Es wäre schlecht, dies in einem Cookie zu speichern, da all das mit jeder Anfrage verschickt wird und viel Verkehr verursacht. Wir denken darüber nach, etwas zu implementieren, das der Nachrichtenarchivierung von XEP-0136 ähnelt.

Um es auf den Punkt zu bringen, mussten wir uns mit dem Patchen/Erweitern von strophe.js und punjab befassen und wir ändern die Standards etwas. Aber es funktioniert jetzt gut und ich bin gespannt, wie dieses Setup in der Beta funktionieren wird.

+0

Ich bin gespannt, wie lief es in der Beta? Ich frage, weil ich mich auf eine ähnliche Lösung stürze. –

+1

Sind deine Änderungen zu strophe/punjab auf github zufällig? – Aeon

+0

Ich bin auch neugierig darauf. Kannst du die Änderung teilen, die du an Strophe und Punjab vorgenommen hast? –

3

Meine Lösung:

Jeder Reiter seine eigene Verbindung auf andere Ressource, die alle mit der Priorität 1.

In Openfire hinzufügen Server-Variable route.all-resources: true
Nachrichten werden auf alle Ressourcen übertragen.