Wondering about best practices on how to use HttpConnection with J2ME, I had a peek at the sources and to my surprise, I found out, that HttpConnection should offer both keep-alive and chunking without any additional application code (e.g. adding http headers).
The implementation of HttpConnection uses an internal connection cache, so your application code can happily create – Connector.open(“http://…”, …) – and close connections and still transparently re-use the underlying TCP-connections as per HTTP/1.1 Keep-Alive specs, provided the operations being performed on those connections do not preclude Keep-Alives (e.g. by using the request property “Connection Close”, forcing HTTP/1.0, encountering any errors, or just the server plainly rejecting keep-alives).
It is a common misconception, that in order to use Keep-Alive, the HttpConnection object should be kept open. Just don’t do that! Instead always tidy-up resources you’re fed up with, as is the case with HttpConnection that is best used for a single transaction (request-reply) only. HttpConnection will transparently take care of caching the underlying TCP socket connection for you.
HttpConnection appears to be far more powerful than most J2ME programmers suspect. My advice: If you are not completely sure whether a particular option, header or application code is required, just leave it out and see what happens. For instance, HttpConnection will either add a Content-Length header (provided the content does not exceed its output buffer) or enable chunking (again adding the appropriate header) on its own and in a way completely transparent to your application code.
I myself had to learn it the hard way after having set up an implementation for chunking of my own. Not before trying to find out about how to properly interface my implementation to HttpConnection (and peeking at its sources), I realized that it’s all there already – ready to be used for free without even having asked for it 🙂
I was able to verify this behavior using a Nokia 6131 NFC mobile device (CLDC-1.1 + MIDP-2.0) and GlassFish v2ur2. It works like a charm!
The automatic keep-alive may not be what you want when your mobile pays for each second of online access. Keep-Alive can easily be disabled by calling conn.setRequestProperty( “Connection”, “close” );.
Your actual mileage may vary 😦 The behavior of the implementation on your phone might be inferior to the one I dealt with (Nokia with lots of implementation code from Sun – judgement derived just from looking at package names) . Nick reports about some of his amazing experiences in his post Using HTTP-Over-Socket and HTTP Proxy in J2ME Applications.
My test responder is implemented in Grails and it succeeds in chunking but fails the keep-alive test (i.e. multiple socket connections are being established) when being run in developer mode from Grails built-in Jetty-Container (i.e. grails run-app). Don’t know (and don’t care), whether this is due to Jetty or Grails running in development mode.
I would have liked to post this as a comment to Codepimps’ article at http://codepimpsdotorg.blogspot.com/2008/12/every-byte-counts.html, however I did not succeed in talking Blogger into accepting my WordPress.com account 😦