On Thu Apr 19 05:48:56 2012, Mike Mahoney wrote:
I propose to refactor BOSH from the current long polling
implementation using Jetty-specific continuations to Servlet 3.0,
which is web container agnostic.
I definitely think this is a step in the right direction. However,
after spending the last 3 weeks really exercising the BOSH
implementation I think there are a couple fundamental changes that we
should consider. So, since you asked... :-)
1. If people are using BOSH, it probably means that Vysper is
embedded in their servlet application. So the Bosh piece needs to be
easily accessible to someone else's servlet code. I'd like to move
towards implementing a 'Connection Manager' endpoint. This endpoint
would know how to communication with the Vysper runtime, and also
present an API that servlets could use. I still think Vysper would
need to implement a reference servlet that uses this connection
manager. Other people could then use that as an example of how to
integrate it into their servlet code.
+1
2. The BoshBackedSessionContext's requestsWindow is sort of playing
double duty. The first element in the Map is always the next request
that needs to be responded to, but it is not necessarily the next
item to be processed by the BoshHandler. I really think that the
processing of stanzas should be completely separate from the tracking
of outstanding requests.
I've tried to add guarding and error handling, but I'm only getting
familiar with the code and re-reading XEP-0124.
3. The BoshHandler.process() method needs refactoring. Right now it
both inserts into the session's requestsWindow, and extracts requests
out of it. If the insert happens to cause an error and the session
has to be closed, then the extraction can easily cause problems.
ok. We should have a JIRA to keep track of it.
The
extraction of incoming stanzas should be done by the connection
manager in a separate thread.
I think it already is done in a separate thread, isn't it? I will take a
closer look.
4. It would be great if there was a way to bootstrap session creation
outside of the standard XMPP session negotiation. We've implemented
a custom BoshHandler.createSession(Entity e) method that we call from
a special interface in our own servlet. This allows a user that has
already logged into a web application to get a BOSH session without
having to re-autenticate. The stophe.js lib has a nice attach()
method that makes doing something like this easy from the client.
+1
Session attachement is described in Jack Moffitts book "Professional
XMPP", chapter 12.
We should have a JIRA to keep track of this feature
Here's our custom createSession for anyone interested:
public BoshBackedSessionContext createSession(Entity entity) throws
BindException { BoshBackedSessionContext session = new
BoshBackedSessionContext(this, serverRuntimeContext,
inactivityChecker); session.setRid(Math.round(Math.random() *
10000)); session.setWait(60); session.setHold(1);
session.setBoshVersion("1.6"); session.setXMLLang("en");
session.setClientAcknowledgements(true);
session.getStateHolder().setState(SessionState.AUTHENTICATED);
session.setInitiatingEntity(entity); session.bindResource();
sessions.put(session.getSessionId(), session);
return session; }
5. The implementation has to be careful to always return a valid BOSH
body to the client. For example, if BoshHandler.process() detects
one of the error conditions at the beginning of the method, then the
result will be an empty HttpResponse being sent back to the client.
Maybe some clients deal with this, but I know we ran into problems
with strophe.js.
+1.
These are just a few thoughts I've had while digging into this code.
We're in the middle of a product release at work, so I'm pretty
swamped right now, but I'd be interested in working on an updated
design and implementation for BOSH.
All the best for your release.
Great points. Thanks for the post.
Bernd