Subject: [hybi] thewebsocketprotocol #28 (new): Fragmentation

From: "hybi issue tracker" <[email-masked]>
Date: Mon, 22 Nov 2010 17:07:35 -0000

#28: Fragmentation

 4.3.  Fragmentation

    o  Note: There is an open question as to whether control frames be
       interjected in the middle of a fragmented message.  If so, it
       must be decided whether they be fragmented (which would
       require keeping a stack of "in-progress" messages).

-- 
----------------------------------+-----------------------------------------
 Reporter:  sm+ietf@…             |       Owner:     
     Type:  defect                |      Status:  new
 Priority:  major                 |   Milestone:     
Component:  thewebsocketprotocol  |     Version:     
 Severity:  -                     |    Keywords:     
----------------------------------+-----------------------------------------

Ticket URL: <http://trac.tools.ietf.org/wg/hybi/trac/ticket/28>
hybi <http://tools.ietf.org/hybi/>
The Hypertext-Bidirectional (HyBi) working group will seek
standardization of one approach to maintain bidirectional
communications between the HTTP client, server and intermediate
entities, which will provide more efficiency compared to the current
use of hanging requests.

---

From: Zhong Yu <[email-masked]>
Date: Mon, 22 Nov 2010 12:32:50 -0600

I think the answers to this question depend on specific programming
models, therefore they are best addressed by applications/frameworks.
WS protocol doesn't have to support streaming - that's the job of
frameworks. A single layer shouldn't mix streams and messages. (So we
have streaming framework, on top of WebSocket frames, on top of TCP
stream, on top of IP frames, on top of electronic stream, on top of
quantum of photons... It's turtle all the way, but there is only one
turtle at each level)

-- Zhong Yu

---

From: "hybi issue tracker" <[email-masked]>
Date: Mon, 22 Nov 2010 19:03:30 -0000

#28: Fragmentation

Comment(by jat@…):

 I thought this was agreed in the discussions, though apparently not
 reflected in the draft.

 I believe we agreed that control messages could not be fragmented and
 could appear in the middle of a fragmented message (though "flattening"
 the opcode space so that control opcodes are intermixed with data opcodes
 makes it harder to specify that in a forward-compatible way).

Ticket URL: <http://trac.tools.ietf.org/wg/hybi/trac/ticket/28#comment:1>

---

From: John Tamplin <[email-masked]>
Date: Mon, 22 Nov 2010 14:09:15 -0500

> quantum of photons... It's turtle all the way, but there is only one

I disagree completely.  WebSocket fragmentation isn't about supporting
streams but rather supporting senders that don't know the length up front
and advanced uses such as multiplexing.  The unit of communication via
WebSocket is always a message.

This question has to be answered in order to interpret a stream of frames
properly.  One of the following must be true to have a single unique
interpretation of a sequence of frames:

- control frames can't be fragmented
- control frames cannot be inserted in the middle of a fragmented message
- there must be a way to differentiate a control fragment from a data
fragment
- the receiver must keep an arbitrarily deep stack of in-progress messages

-- 
John A. Tamplin
Software Engineer (GWT), Google

---

From: Zhong Yu <[email-masked]>
Date: Mon, 22 Nov 2010 13:36:05 -0600

> streams but rather supporting senders that don't know the length up front

if fragments of a single message must be consecutive and there cannot
be gaps between, then it is equivalent to in-frame chunking. That
sounds simple and fine.

> and advanced uses such as multiplexing.

for example?

> The unit of communication via

---

From: Greg Wilkins <[email-masked]>
Date: Wed, 24 Nov 2010 10:55:52 +1100

> - control frames can't be fragmented

+1

> - control frames cannot be inserted in the middle of a fragmented message

I think this is reasonable to allow in the base protocol.  It would
probably simplify the implementations of things like keep alive pings,
so that these can be sent if there was a long pause between fragements
of a message.    It would also allow a close control frame to be sent
without waiting for a message to complete.

> - there must be a way to differentiate a control fragment from a data

We have that already- yes?

> - the receiver must keep an arbitrarily deep stack of in-progress messages

I think this kind of complexity need only be supported by stacks that
support a MUX extension.  Once such an extension is accepted, then I
would expect that control frames and messages fragments from different
channels/streams will be able to be interleaved and well defined rules
will need to  be established for interpreting how control frames
relate to partially sent/received messages.

cheers

> _______________________________________________
> hybi mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/hybi
>
>

---

From: Zhong Yu <[email-masked]>
Date: Wed, 24 Nov 2010 04:03:11 -0600

The most important thing I think is the abstraction WS provides to app
developers. Right now the abstraction is simple -- one message after
another. The simplicity is a good thing, if it is compromised I don't
know what websocket is supposed to be any more. Let's just kill
fragments and don't even think about any advanced features that depend
on it. Every message stays in one frame, even ones with unknown
lengths.

- Zhong Yu

---

From: Jamie Lokier <[email-masked]>
Date: Wed, 24 Nov 2010 10:40:50 +0000

Zhong Yu wrote:
> know what websocket is supposed to be any more.

Right now, WS provides *two* abstractions: The one to app developers,
and the one over TCP.

Some of us believe they *should not be the same* due to network
engineering issues *because that makes the app developer's job easier*.

Right now, the "simplicity" of WS means *robust* apps need to
implement half of TCP in Javascript on the client, which is not a good
sign.  (For example the "tic tac toe" example, which is supposed to be
simple, can lock up on real networks: No more moves when a TCP is
silently dropped.  A HTTP equivalent doesn't have this problem.)

Why do you think the two abstractions should be the same?

HTTP's app abstraction is quite different from its wire abstraction,
and that separation has worked extremely well for everyone.

> Let's just kill fragments and don't even think about any advanced
> features that depend on it. Every message stays in one frame, even
> ones with unknown lengths.

Technical question: How would you send a binary message with unknown
length, in a single frame without fragments?

That said, I'm not sure why we need to support messages with unknown
lengths in advance in the simplest protocol level anyway.  Is there a
use case for control frames such as graceful close or error indication
in the middle of a message?

The use cases which come to my mind are: Keepalives - those are
desirable in th middle of a large message, if the message is being
generated slowly; and graceful close/error indicator, in the case of
WS being forwarded over a proxy.  But neither of those behaviours are
in the simplest protocol.

Imho, what we do need to do, though, is make it clear what proxies are
supposed to do when forwarding a large or unbounded-length WS
message...  Forward every byte as soon as they receive it, buffer
whole messages if they so wish, or something between?  The first is
inefficient over TCP (it can make unnecessary packets and unnecessary
delays), and the second would lead to breakage because proxy behaviour
would be different from non-proxy behaviour.  Right now, proxies doing
CONNECT implement the first.

-- Jamie

---

From: Zhong Yu <[email-masked]>
Date: Wed, 24 Nov 2010 12:01:23 -0600

> implement half of TCP in Javascript on the client, which is not a good

That's where frameworks come in, which can provide degrees of
robustness suitable for different applications. I don't think WS
should or could address these application level concerns.

The #1 feature needed for robustness is auto reconnect. Nobody
proposed to build that feature in the WS protocol.

> Why do you think the two abstractions should be the same?

They should not be. But no matter how complex the protocol must
become, I wish it won't jeopardize the simple application abstraction.
I don't want WebSocket to become WebService, and everybody needs to
buy a 1000 page "The Definitive Guide".

> length, in a single frame without fragments?

chunks within a frame. frames can't overlap, therefore messages cannot overlap.

> generated slowly;

If it is so slow and it exceeds the timeout, who are we to say that
the connection is "alive"? The ping-pong test certainly says nothing
about application liveliness. I don't see the point.

> and graceful close/error indicator, in the case of

---

From: John Tamplin <[email-masked]>
Date: Wed, 24 Nov 2010 14:04:34 -0500

> buy a 1000 page "The Definitive Guide".

A simple implementation, which does not implement any extensions, is still
quite simple.  See
http://code.google.com/p/websocket-draft-eval/source/browse/trunk/src/com/google/websocket/SimpleWebSocket.java
for
an example.

We are making slow enough progress as it is -- we don't need to be
revisiting framing decisions agreed upon months ago.

> chunks within a frame. frames can't overlap, therefore messages cannot

And how do you identify the chunk and frame boundaries if you don't know the
length up front?  This exact suggestion was made and rejected months ago --
please read the archives.

---

From: Jamie Lokier <[email-masked]>
Date: Wed, 24 Nov 2010 20:37:57 +0000

> should or could address these application level concerns.

Certain concerns *cannot* be addressed at the Javascript level, or
they are hard to do.  Some of them are technical (connection/keepalive
aggregation, network error indication); some of them are social
because authors are motivated by self-interest, not aggregate
behaviour.  Frameworks don't make independently-written components on
the same page/server share connections/keepalives, and even *using* a
single framework, it's not clear if it's technically able to share
connections to the same server.

Ironically this makes HTTP way more efficient than WebSocket for some
kinds of small messaging when multiple pages are open, yet less
efficient for a single page and few components.  You can guess which
will be optimised for, by most authors.  The effect is not insignificant.

> proposed to build that feature in the WS protocol.

For a very good reason: No matter how much the system tries to auto
reconnect, at some point the application *must* be able to handle the
fact that connection is lost and can't be restored.  They must also
decide what to send on reconnection; queuing everything and resending
it all would be disastrous for many apps, after a long delay.

Since applications must handle that anyway (and it's easy to script),
there is little point *for the app* to have WS doing it automatically.

(There is a network reason though: Local congestion collapse, and
router NAT overflow, due to many pages/components repeatedly retrying
connections without backoff...)

If anything, #1 is a way to *detect when* a connection is dead and a
reconnect advisable.

> buy a 1000 page "The Definitive Guide".

I'm pretty sure everyone in the design discussions agrees on keeping
the application abstraction simple.

I'm dismayed that attempts to make the application abstraction *simpler*
by making the network layer work a bit harder are repeatedly
misunderstood as the opposite.

A glaringly obvious example is the way, as you've pointed out, that
the only robust way to use *current* WebSocket is with a "framework".
Many of the protocol proposals make it robust, and scale better, while
using the WebSocket object directly from scripts - without changing
the application abstraction *at all*.

> about application liveliness. I don't see the point.

It's not to detect application aliveness!!  That's a different
problem, which needs the app to explicitly participate.

You need regular keepalives to keep TCP connected through a NAT.  The
interval needed for that varies (a lot), but I have seen NATs drop
connections after as little as 30 seconds TCP inactivity, including
delays from TCP's own timers.

The problem of NAT is only going to get worse.

I see nothing wrong with applications caring about their own behaviour
(such as liveness / app reconnect/resync logic), while the silly NAT
behaviour is something they shouldn't have to deal with.

The simplest abstraction is probably a pipe that stays open as long as
the network can sustain it smoothly (i.e. without long interruptions
and unsustainable queueing).  Whether the pipe carries
messages/text/bytes is less important.

That implies NAT keepalives, that can always be sent, even in the
middle of a long message if they can be produced incrementally.

-- Jamie

---

From: Jamie Lokier <[email-masked]>
Date: Wed, 24 Nov 2010 22:08:58 +0000

Jamie Lokier wrote:
> Frameworks don't make independently-written components on

Sorry, I missed a few words:

  Even using a single framework, it's not clear if it's technically able
  for *multiple open windows/tabs* to share connections to the same server.

-- Jamie

---

From: Greg Wilkins <[email-masked]>
Date: Thu, 25 Nov 2010 16:21:29 +1100

Zhong,

I don't think anybody has suggested changing the WS API abstraction.
It is and should remain a simple stream of complete messages.

But it is an abstraction! which means that it is hiding the details of
what actually happens underneath.   There are some good technical
reasons for supporting fragmentation below the API abstraction and we
have had the discussions at great length to determine if these reasons
are good enough to justify the increase in the complexity of the
protocol level abstraction.

The current consensus appears to be that fragmentation is a needed
technical feature in the framing layer.  While good reasons might be
presented that may again change this consensus, I don't think the
simplicity argument is one such reason.  That case has already been
made and failed.      If you do have some new insights on the
cost/benefit of fragmentation, then we should discuss them, but we do
also need to be very careful that we don't go over ground that has
already been well debated.

And I repeat that I have not seen anybody advocate that fragmentation
should be exposed in any way to via the WS API.

regards