Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XMPP web chat: how to resolve multiple tabs/windows?

Tags:

chat

xmpp

strophe

We have a site and we developed a chat system for it using strophe.js library and ejabberd XMPP server. We use session attachment that was initiated with PHP (using an in-house library). What we do is get the RID and SID from the PHP script, then use strophe's session attachment. The said RID and SID is stored on a cookie and the RID value on the cookie is updated every update of the RID on strophe.js. (This is so we can reuse the Session ID on page refresh/navigation to other places on the site)

We now plan on having it work on multiple tabs/windows. I've observed Facebook's implementation, and for each tab there is a long polling request to a certain domain. This domain is different for each tab. For example, tab one would be 0.86.channel.facebook.com. Second tab would be 1.86.channel.facebook.com. As I understand this is to solve browser limitation of 2 active requests to a certain domain. How is this multiple domain solution implemented?

Next would be on the chat sessions itself. The chat sessions would be different per tab right? How would the UI be synched with each tab like Facebook? My idea is, per every action, a message would be sent to the user's own JID containing the action done related to chat. For example, opening a chat window would send a message stanza like this:

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

and this would be caught on the chat client and the UI would be adjusted accordingly (in this case, opening a chat box for a contact).

Any suggestions/comments on this implementation?

Thanks!

like image 208
putolaruan Avatar asked Oct 27 '10 09:10

putolaruan


2 Answers

Me and my team were working on the exact same problem - only that we use Openfire instead of Ejabberd (mostly cause we have Java skills but are not familiar with Erlang). Our company is building browsergames.

Our solution consists of:

  • XMPPHP - for prebinding
  • Strophe.js - for session attaching (modified)
  • Punjab - as Connection Manager (extended, modified)
  • Openfire - as XMPP server

We use punjab, because the BOSH implementation of Openfire did not seem to work very well with the other components at first.

Basically we decided not to create a session for each tab. This is due to the fact that some of our games work the way usual websites do: a click on a link will request a complete new page (whereas the newer games fully work in ajax and most of the GUI stays the same). So in other words: our web based chat will have to work in environments where the user 'moves over the website'. One session for one tab would mean a new session for each page request, which seems like a huge overhead, because players often click pretty quickly. So - we wanted one session to be created and stick to a player.

To solve that we - like you - modified strophe.js to read/save the RID in a cookie, so all tabs know the current RID and increment to a correct value. Another thing is, we made Strophe add a CID to the body of the XMPP stanzas. CID like Client ID. I'll explain the use soon..

Next the plan was to modify two things in punjab. First we added a class that replaced the usual way that waiting requests are stored in punjab. Waiting BOSH requests are now saved in a dictionary with the CID (that strophe.js now adds to the body of every request) as the key. When another request from the same tab arrives punjab then knows which waiting request to send an empty answer to. If there are new stanzas to be delivered punjab will send these out to all waiting requests in the dictionary. So an incoming message is distributed to all tabs. Second we added a few lines, so that a message that has been sent from one tab is delivered 'back' to all other tabs right away. So the message can appear in the other tabs history, too.

Of course there are other problems that have to be faced, like not loosing the chat history in the GUI when the player moves on to the next screen. Storing this in a cookie would be bad, since all that stuff is sent out with each requests and causes lots of traffic. For this we thinking of implementing something which is similar to XEP-0136 message archiving.

So to put it in a nutshell, we had to dealt with patching/extending strophe.js and punjab and we are modifying the standards a little. But it works fine for now and I am excited to see how this setup will do in the beta.

like image 128
Jost Avatar answered Oct 16 '22 17:10

Jost


My solution:

Each tab has his own connection on different resource, all with priority 1.

In openfire add server variable route.all-resources: true
Messages will be broadcast to all resources.

like image 26
Grigoryj Piroryj Avatar answered Oct 16 '22 15:10

Grigoryj Piroryj