Subject: [hybi] Suggested improvements to WebSocket

From: Stephen Williams <[email-masked]>
Date: Tue, 22 Feb 2011 01:49:59 -0800

Apologies for not joining and suggesting earlier.  Please point out any prior conversation of something like these points.

Mini-intro: I've studied a lot of existing protocols for a long time, and designed and built a number of my own.  I've designed 
rate-based, scalable, high-performance protocols for IM/presence, video streaming, and bulk de-duplicated backup.  I worked on the 
first IETF working group for presence/IM (which XMPP was part of) and the W3C XBC and EXI binary XML working groups.

How does content type and encoding interact with WebSockets?  Can each message be different?

As per the Design Philosophy in 1.6, these likely should be extensions.  However, I would argue that these are important, needed in 
enough circumstances, and general enough to be part of the specification.  Perhaps a raw vs. cooked model makes sense.

I'll suggest these as optional framing layers inside a WebSocket message, although some or all of this could be more integral to the 
overall framing.

Compression: Compression always needs to be supported whenever encryption of any kind is performed, as after such a transformation 
compression is not possible.  A compression type and version should be specified.  The content of a compressed message should be 
interpreted as if it had been received uncompressed.

Batching: Multiple messages may be combined into a batch of messages.  The batch, as a single WebSocket message, should be processed 
as if the contained messages had been received individually.

Encryption: WebSocket security measures may be enough.  However, for another layer of security, or perhaps for selective message 
access, an encryption message container should exist.  This specifies encryption type/parameters and identity of key.  The contents 
of an encrypted message are interpreted as if they weren't encrypted.

Channelization: A communication link should support a simple channelization capability, similar semantically to multiple parallel 
TCP connections, but implemented as multiplexed packets.  The mostly ignored IETF BEEP (originally BXXP) protocol has a nice 
channelization design.)  XMPP effectively has channelization, as does RabbitMQ, ZeroMQ, etc.

Rich Message passing (or some similar moniker): HTTP 1.0 is simple client/server: Half duplex, synchronous, request->response.  HTTP 
1.1 added asynchronous, pipelined messaging but the model was still request->response.  Only through inefficient and fragile hacks 
like Comet is this basic model overcome.  WebSockets, as defined now, provides a more sophisticated peer model that is 
request->response and response<-request.  However, the most general and complete logical model in widespread use is embodied in 
presence/IM systems like XMPP: They include logical, overlay concepts of: named endpoints (and sometimes sub-endpoints), 
authentication/identity of endpoints, logical routing of messages, and both basic logical communication models: point-to-point async 
message queues (an IM/chat message) and publish/subscribe (presence updates/subscription).  A system that includes all of these 
building blocks can implement most logical communication models as subsets.  WebSocket need not include much to allow various 
implementations of these concepts (perhaps via JMS, RabbitMQ, XMPP).  Not only would XMPP over WebSocket probably make sense, but 
WebSocket compatible API messaging should be able to be transported over XMPP.

The most important missing capability of WebSocket (and most current communication mechanisms):
Windowed, logical end-to-end flow control: Link level flow control (TCP) works well.  However, in any 3+ tier system, or any system 
where more than one link is involved in a communication chain, there are various inefficiencies and failures that can occur when 
there is no real end-to-end flow control.  The right way to implement this feature is to support a simple representation of "message 
processed request" / "message processed", including roll up of multiple notifications into a single request.  (Careful choice of how 
to report and coalesce message identification is needed.  Probably, a single concept can handle two or more types of situations: An 
ack of "N units processed" where each message implicitly or explicitly notes how many units (bytes, message count, etc.) it 
represents.)  For a more advanced implementaiton, as long as proper timestamps are included, transfer and processing rates can be 
estimated and the processing can be dynamically rate-based.  The core concepts: A sender, when queuing a message for a particular 
channel, periodically adds metadata that requests an ack that prior messages had been processed by the final endpoint.  (Whatever 
that means to the application involved.)  Each communication link passes on the request, with or without transformation mapping 
(needed at processing tiers where data is consumed and new data is created).  The final tier transmits back the acknowledgment which 
is propagated to the sender.  The goal of all of this is to control the amount of messages/data outstanding on a particular channel 
and to prevent excessive buffering or overrun in communication and processing tiers.  This optimizes network, buffering, and 
latency.  Note that the concept is explicitly about when a message is processed, not when it is communicated.  Although the latter 
might be helpful in optimizing recovery from a failure (and could also be supported), it does nothing to reliably and most 
efficiently get past synchronous client/server.

All of the complexity is in the application endpoints which are deciding when to send a message and when to ack its processing, plus 
how to recover from a lost connection or restarted endpoint.  A simple application can implement very simple versions of these.

Applications that need these features are not hard to find: uploading or downloading anything in bulk, especially live multi-media 
data or bulk data replication, pipelined application transactions, and interactive gaming.

Stephen
-- 
Stephen D. Williams [email-masked] [email-masked] LinkedIn: http://sdw.st/in V:650-450-UNIX (8649) V:866.SDW.UNIX 
V:703.371.9362 F:703.995.0407 AIM:sdw Skype:StephenDWilliams Yahoo:sdwlignet Resume: http://sdw.st/gres Personal: http://sdw.st 
facebook.com/sdwlig twitter.com/scienteer

---

From: Andy Green <[email-masked]>
Date: Tue, 22 Feb 2011 10:09:32 +0000

On 02/22/2011 09:49 AM, Somebody in the thread at some point said:

Hi -

> As per the Design Philosophy in 1.6, these likely should be extensions.

Yeah or done as protocols or are already defined.

> Compression: Compression always needs to be supported whenever

Already supported: there is a compression extension defined.

> Batching: Multiple messages may be combined into a batch of messages.
> The batch, as a single WebSocket message, should be processed as if the
> contained messages had been received individually.

Already supported: Any peer or intermediary can decide to do that 
already since framed data is just streamed and interpreted bytewise; if 
it doesn't mind introducing a bit of latency it can batch stuff before 
spilling it.

> Encryption: WebSocket security measures may be enough. However, for

SSL is enough for most anything.  If you want more either select a funky 
SSL cypher, define an encryption extension that operates inside the SSL 
tunnel or define your protocol to encrypt the payload.

> Channelization: A communication link should support a simple

Muxing will come as an extension.

> subsets. WebSocket need not include much to allow various
> implementations of these concepts (perhaps via JMS, RabbitMQ, XMPP). Not
> only would XMPP over WebSocket probably make sense, but WebSocket
> compatible API messaging should be able to be transported over XMPP.

This is all the business of the protocols to define how they like on top 
of websockets.

> Windowed, logical end-to-end flow control: Link level flow control (TCP)

It sounds like websockets already provides the basis and you just need 
to decide a protocol name and define that using the existing websockets 
transport to have all those features you want.  Without further delaying 
the actual websockets spec.

-Andy