<< 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.
A Connection Manager endpoint would be really, REALLY great.
In addition to some of the issues that we have already discussed there is
another that I have been working around over the past week.
XEP-0206 Section 7 Recipient-Unavailable
This is not implemented, I am not sure it was even considered.
While looking into ways to implement this one thing became painfully
obvious, using the StanzaWriter interface is an upstream dead end. (Which I
suppose makes some sense if you are looking to decouple the CM from the XMPP
core).
When BoshBackedSessionContext.close is called the DelayedResponseQueue
(Which is essentially the CM's buffer) needs to be drained and Message and
certain IQs persisted.
I implemented as much as I could filtering the stanzas in the DRQ and
grabbing a handle to the OfflineStanzaReceiver (it's a little messy but it
does work pretty well).
The last part that I could not implement was the handling of persistence
exceptions which should return an error back to the sender. I do not see a
way to get back downstream to handle this unless the implementation is more
in line with the core Endpoint and StanzaRelay implementations.
So really it comes down to a design approach, I believe there are definitely
advantages to having the Bosh CM run collocated with the Vysper core but it
does make decoupling it from a specific servlet implementation more
challenging.
-Paul
-----Original Message-----
From: Mike Mahoney
Sent: Wednesday, April 18, 2012 11:48 PM
To: [email protected]
Subject: Re: [VYSPER] [PROPOSAL] Migrate BOSH to Servlet 3.0
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.
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.
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. The extraction of incoming
stanzas should be done by the connection manager in a separate thread.
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. 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.
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.
I'd love to hear other people's thoughts/ideas as well.
-Mike