jsr340-experts@servlet-spec.java.net

[jsr340-experts] Re: Websockets

From: Alex <alex_at_caucho.com>
Date: Fri, 27 May 2011 08:05:02 -0700

> Well I guess it can be read either way.
>
> For those interested, here is the Caucho API:

> http://caucho.com/resin-4.0-javadoc/com/caucho/websocket/package-summary.html

Yep, that's the current link. A small write up by Scott explains our design approach:

Design notes:

General:
======

 1. The API is designed to be more minimal than a final design would be to make it easier to focus on the critical design decisions, and to avoid feature bloat if possible.

 2. The key model is the InputStream/Reader and OutputStream/PrintWriter stream-based data model, following the Servlet API. It's expected that application frameworks may create String or byte array APIs on top, but the low-level servlet API is a simple stream API which scales from tiny messages to very large messages.

In other words, I'm expecting this API to be aimed more at the framework developers, just like the servlet API, not necessarily the end users. (In part, because frameworks should really be exposing a specific WebSocket sub-protocol, like a JSON message system, not the raw stream.)

 3. The API is at the message layer, not the frame layer. The frame layer should be an implementation detail for now (e.g. supporting muxing or compression, implementation efficiency, etc.). While it may eventually be worthwhile to expose a standard frame API/SPI for WebSocket extensions, I think it's best put off for a bit, like the Servlet Filters were, until the Servlet users and also the WebSocket community understands better what extensions should look like. I think extension implementation will be rare and might always be container features. So keeping focused on the key application message layer seems like a better move for now.

 4. The WebSocketContext and WebSocketListener do not have any servlet API dependencies because they should also be used for the client API. (Because WebSocket is symmetrical once established, it would be a mistake to have separate Java client and server APIs.)

WebSocketServletRequest:
=================

 1. This is an interface only to decouple it from the Resin implementation. I'd expect it to be a HttpServletRequest method in the servlet spec.

 2. startWebSocket is meant to resemble startAsync. It issues the upgrade response. It's the responsibility of the application servlet to check headers and set the "Protocol" header before calling startWebSocket.

 3. The WebSocketListener is passed as an argument (instead of a setter) because client messages might be delivered immediately, even before the startWebSocket returns.

 4. The WebSocketContext is returned so the server can start sending messages.

WebSocketContext:
============

 1. intended to resemble AsyncContext

 2. Does _not_ have servlet API dependencies because it is intended to be a valid Java WebSocket client API.

 3. _not_ thread-safe. (Thread safety would be impossible in any case, because the message doesn't complete until the output stream is closed.)

 4. Only two major methods: startTextMessage() and startBinaryMessage().

 5. Message ends when OutputStream.close() or Writer.close() is called.

 6. Implementations MAY reuse the OutputStream/Writer objects, like the ServletRequest spec.

 7. (Extensions deliberately ignored in the draft proposal to keep things simple.)

WebSocketListener:
============

 1. somewhat similar to async listeners, but the listener is unique.

 2. the listener is serialized/single-threaded, e.g. a new message will not be delivered until the application returns from onReadBinary/onReadText.

 3. WebSocketContext is passed as an argument for timing reasons (i.e. there may be a message before the startWebSocket returns.)

 4. message reading is complete when the onReadBinary/onReadText returns. If more data is available in the message, the implementation skips the rest of the message.

 5. (Extension data again deliberately ignored in the draft to keep things simple.)

Final general notes:
=============

 1. The stream API at the message layer is important to me (as opposed to a String/byte[] API at the frame layer.)

 2. Any frame/extension API/SPI should be an added/lower layer (like the CDI extensions), not part of the messaging layer. (And should probably be postponed for now.)

 3. The Listener/Context is nice, but it's not as important as the core stream.

 4. I expect some complications to be added for extensions (possibly in the Context), but wanted to focus on the core API for a first proposal. So I expect the onReadBinary and startBinaryMessage signatures to change.

Alex
>
>
> On 27 May 2011 18:42, Remy Maucherat <rmaucher_at_redhat.com> wrote:
>> On Fri, 2011-05-27 at 18:38 +1000, Greg Wilkins wrote:
>>> On 27 May 2011 17:32, Remy Maucherat <rmaucher_at_redhat.com> wrote:
>>>> On Fri, 2011-05-27 at 08:21 +1000, Greg Wilkins wrote:
>>>>> I make no representations that this is the best way to proceed, or
>>>>> even a good way... it is just how we have done it so far. Users have
>>>>> been warned that significant changes to this API are likely.
>>>>
>>>> Besides the upgrade mechanism, this has not been mentioned as being in
>>>> scope for this JSR. Which is quite understandable IMO, it's a lot of
>>>> spec work on something that is not finalized yet.
>>>
>>> Remy,
>>>
>>> it is in the JSR340 proposal:
>>>
>>> http://www.jcp.org/en/jsr/proposalDetails?id=340
>>
>> "Enable support for WebSockets and other such protocols that work on /
>> do initial handshake over HTTP."
>>
>> --
>> Remy Maucherat <rmaucher_at_redhat.com>
>> Red Hat Inc
>>
>>
>
>