This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 12102 - WebSocket protocol update time
Summary: WebSocket protocol update time
Status: RESOLVED FIXED
Alias: None
Product: WebAppsWG
Classification: Unclassified
Component: WebSocket API (editor: Ian Hickson) (show other bugs)
Version: unspecified
Hardware: PC All
: P2 normal
Target Milestone: ---
Assignee: Ian 'Hixie' Hickson
QA Contact: public-webapps-bugzilla
URL:
Whiteboard:
Keywords:
Depends on: 11834
Blocks:
  Show dependency treegraph
 
Reported: 2011-02-17 01:51 UTC by Ian 'Hixie' Hickson
Modified: 2011-06-14 07:47 UTC (History)
20 users (show)

See Also:


Attachments

Description Ian 'Hixie' Hickson 2011-02-17 01:51:50 UTC
* onclose should have unsigned int reasonCode and DOMString reasonMessage.
* readonly attribute DOMString extensions; // ianf will provide a hook
* send() takes some sort of binary argument and
* onmessage event.data exposes binary data
* check through http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol to make sure the hooks still work
Comment 1 Adrian Bateman [MSFT] 2011-02-24 23:43:34 UTC
At Microsoft, we've been reviewing how the binary support now enabled by the WebSocket protocol might be exposed in the API.

In line with Ian's notes in this bug, we'd like to see the send() method accept a Blob argument that indicates to the API that a binary message should be sent. The existing definition with a string should send a text message. Implementations can decide how they choose to break up the message into intermediate frames since this isn't exposed to the API.

On the receiving side, we think that the event.data attribute should contain a Blob if the message was a binary message and a remain as a string for text messages.

Since MessageEvent already defines data to be of type 'any', the change here would be to describe the semantics of text vs. binary messages in section 5 of the spec.

For the send method, we'd expect an overload of send in section 4 as follows:
    void send(in Blob data);
Comment 2 Sirisian 2011-02-28 07:44:01 UTC
http://lists.w3.org/Archives/Public/public-webapps/2011JanMar/0131.html

>Send would just accept an ArrayBuffer and treat it like an Uint8Array 
> probably. If you said you were using a binary protocol then the onmessage 
> event.data would just be an ArrayBuffer object. Simple. Please don't make it 
> complicated. Don't be like "but people will get confused when their long 
> messages are split between multiple onmessage callbacks." It should just be a 
> pure TCP stream with no special stuff. That is you could get any amount of bytes 
> during a receive just like regular TCP where anything over the MTU is chopped 
up.

I haven't used IE9 so I'm not sure if that has ArrayBuffer yet.
https://developer.mozilla.org/en/JavaScript_typed_arrays/ArrayBuffer
Comment 3 Adrian Bateman [MSFT] 2011-02-28 16:26:43 UTC
WebSockets is a message based protocol - it makes sense to have messages be first class citizens in the API. It's certainly possible to build an alternative API that exposes the data as some kind of stream too but I'm not convinced that's the highest priority here.
Comment 4 Anne 2011-02-28 16:33:06 UTC
ArrayBuffer is fixed size though and much more like DOMString than Blob is. (Blob is disk-backed, asynchronous, etc.) I suspect we want to have both in the end for different type of use cases.
Comment 5 Adrian Bateman [MSFT] 2011-02-28 16:49:10 UTC
Blob is also fixed size and doesn't have to be disk-backed. I agree that having both might be necessary - how would that work on the receiving side though?
Comment 6 Ian 'Hixie' Hickson 2011-02-28 20:06:43 UTC
How easy is it to get data out of a Blob? That'd be my main concern. (And vice versa -- say we used ArrayBuffer or whatnot, how easy would it be to get it into an <img>?)
Comment 7 Ian 'Hixie' Hickson 2011-03-24 21:57:53 UTC
I started doing this but I need a few more hooks on the server spec side. I'll get back to it when that's been updated.

Regarding binary I'm still not 100% sure what to do, but based on the feedback so far here and on various lists I'm leaning towards exposing the data primarily as an ArrayBuffer, except that any Int16Array, UInt16Array, Int32Array, UInt32Array, Float32Array, and Float64Array objects used to read that ArrayBuffer or any ArrayBuffer derived from it must read the data as big-endian (network byte order). It's relatively easy to get a Blob from a TypedArray as far as I can tell (easier than the other way around, which requires using async readers).
Comment 8 contributor 2011-03-24 23:59:52 UTC
Checked in as WHATWG revision r5963.
Check-in comment: WebSockets: add reason and code to the event; also some minor editorial things. More WebSockets changes coming.
http://html5.org/tools/web-apps-tracker?from=5962&to=5963
Comment 9 Adrian Bateman [MSFT] 2011-03-26 03:51:45 UTC
There are use cases for both Blob and ArrayBuffer. While it's possible to convert between the two it's also convenient to be able to specify the preferred type just like with XHR, which supports both.

Supporting both would require a mechanism to specify the preferred type. In fact, as we've been experimenting with the WebSocket API we've found that initiating network I/O from the constructor is somewhat inconvenient. We would much prefer a model more like XHR and feel that this is better for future extensibility as the API develops.

Our proposal to start the discussion:

* The constructor behavior and signature is changed to follow the XHR model. It instantiates a WebSocket object but does not establish the connection.

* A new ready state constant is added to indicate that a WebSocket has been created, but no connection established. 

* A new open method is added to the API to establish the connection:
    void open(in DOMString url);

* A supportedProtocols attribute is added. This is the list of protocols sent by the client to the server during the handshake. This replaces the protocols parameter in the current constructor.
    attribute DOMString[] supportedProtocols;

* Add overloads to send
    void send(in Blob data); 
    void send(in ArrayBuffer data);

* A binaryResponseType attribute is added to the WebSockets interface which can be set to: "arraybuffer" or "blob". The default string "" might default to ArrayBuffer or it might indicate that the client isn't expecting binary data. We'd like to discuss this more.
    attribute DOMString binaryResponseType;

* Message event event.data returns a string for text messages and the type specified in binaryResponseType for binary data. Message event only fires when the entire message is available.
Comment 10 Takeshi Yoshino 2011-04-07 09:46:42 UTC
> * The constructor behavior and signature is changed to follow the XHR model. It
> instantiates a WebSocket object but does not establish the connection.
Could you tell us the actual issue with I/O initiation on construction you encountered?

Indeed, we're experiencing a little discomfort for the difference of semantics between XHR and WS, but it's not so critical for now.

> * A supportedProtocols attribute is added. This is the list of protocols sent
> by the client to the server during the handshake. This replaces the protocols
> parameter in the current constructor.
>     attribute DOMString[] supportedProtocols;
You mean that we set this property before calling the open method you suggest? Making this an argument of open method is also an option.

> 
> * Add overloads to send
>     void send(in Blob data); 
>     void send(in ArrayBuffer data);
Fine.

> 
> * A binaryResponseType attribute is added to the WebSockets interface which can
> be set to: "arraybuffer" or "blob". The default string "" might default to
> ArrayBuffer or it might indicate that the client isn't expecting binary data.
> We'd like to discuss this more.
>     attribute DOMString binaryResponseType;
> 
> * Message event event.data returns a string for text messages and the type
> specified in binaryResponseType for binary data. Message event only fires when
> the entire message is available.

I think this is reasonable.

Question is if we require every user-agent to support both.

We should have some way to check if substitution to binaryResponseType has been accepted or not. Maybe rejecting substitution by firing onerror or allowing user to check if it's accepted by evaluating binaryResponseType? By latter, we can fallback to the other if not supported.
Comment 11 Yuta Kitamura 2011-04-08 14:10:17 UTC
My understanding about Blob and ArrayBuffer is:

- ArrayBuffer is a straightforward representation of on-memory binary data. It's fairly easy to read an arbitrary byte from an ArrayBuffer, or to build an ArrayBuffer of a known size.

- Blob is binary data structure whose backing store is (basically) a file. A Blob has a MIME-type (Blob.type) and you can obtain a generated URL for it (createObjectURL) which can be useful for creating an element using received binary data (such as <img>). It's not very easy to read bytes from a Blob. It's relatively easy to build a big Blob incrementally using BlobBuilder.

Considering these characteristics, I've come to the following idea:

========
To receive a binary frame from a server: ArrayBuffer is used by default, but a WebSocket protocol extention is allowed to change the representation of received data.

To send a binary frame to a server: the browser accepts both ArrayBuffer and Blob. By default, Blob's MIME-type property is ignored. However, a WebSocket protocol extension may make use of it.

For example, suppose that "MIME-type" WS protocol extension is defined like:
- Each binary frame may contain a MIME-type in extension-data field.
- If a client receives a binary frame with MIME-type, then it must use a Blob to pass the data to JS. Otherwise, an ArrayBuffer is used.
- If "send" is called with a Blob with MIME-type specified, the client must add a MIME-type to extendsion-data field to that binary frame.

In this way, the server can control the representation of binary data and the client can naturally receive benefit from Blob properties (like createObjectURL).
========

Comments and suggestions are highly appreciated.

PS. I feel unbivalent about ArrayBuffer's endianness problem. Forcing big-endian might work well.
Comment 12 Adrian Bateman [MSFT] 2011-04-08 17:10:49 UTC
I'd prefer not to tie how the data is projected into JavaScript to the protocol. Whether a web application prefers to consume the data as a Blob or ArrayBuffer shouldn't require a change to the server-side. I don't think we need to make an extension for this case. Blobs can be backed by memory buffers as easily as by files.

You do raise an interesting question about what the content type of the Blob should be, especially as this is a read-only attribute of Blob (although slice can be used to "change" the content type). Perhaps it should be an arbitrary type like application/octet-stream.
Comment 13 Yuta Kitamura 2011-04-09 02:54:23 UTC
> Perhaps it should be an arbitrary type like application/octet-stream.
It's okay to leave "type" attribute as an empty string.

I would recommend not using Blob on receipt (at least by default), because:
  - The browser cannot determine the suitable content type. (Note that this is a difference between WebSocket and XHR.)
  - The client application should know the content type (if any), and can easily generate a Blob from an ArrayBuffer:
      var blobBuilder = new BlobBuilder();
      blobBuilder.append(arrayBuffer);
      var blob = blobBuilder.getBlob("image/jpeg");

I think I'm okay with binaryResponseType attribute, though.
Comment 14 Jonas Sicking (Not reading bugmail) 2011-04-09 04:03:46 UTC
The problem with ArrayBuffer appears when you start dealing with very large pieces of data since ArrayBuffer requires the data to be held in memory. If the thing sent over the WebSocket is a 10 or 100 MB large thing it would likely be nicer to have the browser stream the data to a file and then pass around a reference to that in the form of a Blob.

There being no content type is not a problem, just leave the .type attribute as the empty string. ArrayBuffer also does not have a type so I don't see why this would be an argument either way.
Comment 15 Takeshi Yoshino 2011-04-11 05:59:46 UTC
If Blob slicing doesn't copy data (I think it doesn't), setting MIME type to application/octet-stream on invoking onmessage is fine.

---

Now it sounds for me that storage type (Blob or ArrayBuffer) should be determined in advance of the time when we receive and process WebSocket frame octets (not at the time when onmessage handler is invoked) so that we can create a DOM object with appropriate storage (maybe disk-backed Blob for large data) ... (*)

Adrian, are you supposing that a) we leave binaryResponseType mutable after open() call or b) it's mutable only before open()?

We can simply realize both b) and (*).

But substitution to the binaryResponseType property and frame receive occur in different layers asynchronously. I don't come up with any clear semantics that realize both a) and (*).

1. user-agent saves data from network
2. onmessage is invoked

binaryResponseType may be modified between 1 and 2.
Comment 16 Adrian Bateman [MSFT] 2011-04-11 16:34:29 UTC
I would expect that the developer would set binaryResponseType before calling open(). That way the buffering of frames in the message can be optimised by the UA accordingly, possibly including the suggestion that Jonas made.
Comment 17 Takeshi Yoshino 2011-04-13 09:19:19 UTC
(In reply to comment #16)

So, binaryResponseType would be immutable after open call? If so, i'm fine with this. How about making it a parameter of open()? Then, it's clearer that it can be set only before open().
Comment 18 Adrian Bateman [MSFT] 2011-04-13 14:41:27 UTC
(In reply to comment #17)
> (In reply to comment #16)
> 
> So, binaryResponseType would be immutable after open call? If so, i'm fine with
> this. How about making it a parameter of open()? Then, it's clearer that it can
> be set only before open().

You could make it a parameter but as new things are added in the future the list of arguments to open() could get unwieldy. Having a sensible default that you override if you need a different behaviour (in this case maybe ArrayBuffer unless you know you probably want to use an URL or that the data messages may be large) is an alternative.
Comment 19 Yuta Kitamura 2011-04-14 09:37:42 UTC
I'm almost fine with binaryResponseType if the following statement is added:

* If readyState is not CONNECTING on setting binaryResponseType attribute, an INVALID_STATE_ERR exception is raised.
(cf. <http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#the-responsetype-attribute>)

My last concern about binaryResponseType is whether web application authors are really okay with not having the ability to switch the response data type (Blob/ArrayBuffer) in the middle of the WebSocket connection. I guess they want it.
Comment 20 Adrian Bateman [MSFT] 2011-04-15 17:47:26 UTC
(In reply to comment #19)
> My last concern about binaryResponseType is whether web application authors are
> really okay with not having the ability to switch the response data type
> (Blob/ArrayBuffer) in the middle of the WebSocket connection. I guess they want
> it.

We should get some implementation experience to help with this. It's certainly something that could be added later if it turns out to be essential. I'd rather not guess about adding it. We could do this even in CR if necessary.
Comment 21 Adrian Bateman [MSFT] 2011-04-15 17:52:35 UTC
(In reply to comment #0)
> * readonly attribute DOMString extensions; // ianf will provide a hook

We've spent some time thinking about how extensions fit into the web developer picture. So far we don't have any evidence that web developers would need to be exposed to the current proposals for extensions. Since the behaviour and API requirements for future extensions are unknown at this time, we'd prefer to wait to see what extensions emerge before guessing about what API shape might be necessary. For this reason, we don't think an extensions API is necessary in the first version of the API.
Comment 22 Joel Martin 2011-04-16 17:36:34 UTC
Regarding comment #20. I have some implementation experience using WebSockets for binary data in noVNC (https://github.com/kanaka/noVNC) and websockify (https://github.com/kanaka/websockify). I currently use base64 encode/decode to send the binary data as UTF-8. So I am very interested in native binary support  to the WebSockets API (the base64 decode in Javascript obviously adds non-trivial overhead).

For my projects, I prefer an ArrayBuffer to a Blob interface since my primary interest is being able to read/write of bytes and 32-bit words (RGBA pixel data) and having the data in memory seems likely to have more stable performance characteristics.

Being able to switch between ArrayBuffer and Blob dynamically would not be useful for my projects. The data received by noVNC (RFB protocol traffic) is basically streaming data until the message boundaries are determined by the Javascript code after reception. Switching the received data type on-the-fly would require coordination between the client and WebSockets server (websockify) which would probably be more difficult than just creating a new connection.

If dynamic data-type switching is implemented, it will be important to clearly define when the switch happens. For example, if the UA has received two WebSockets messages and the handler for the first message switches the data-type, does the pending message get dispatched using the new type, or only subsequent message received by the UA. From the perspective of the Javascript code, clearly the second message should be the new type, but I suspect this adds   UA implementation complexity. I think dynamic data-type switching should be avoided.


An aside:

I have done some performance testing of ArrayBuffer vs Canvas ImageData vs normal Javascript arrays (one byte per element). I tested on firefox 3.6.X, firefox 4.0, IE 9, Chrome 9, 10, 11, 12 and Opera 11. Across all browsers I tested (Opera and IE9 do not have ArrayBuffer support yet), normal Javascript arrays tend to have the best performance (sequential reads, sequential writes, random reads).

This was an unexpected result to me since ArrayBuffer and ImageData arrays are static size, static typed arrays and designed for performance sensitive operations (2D canvas, WebGL). My assumption is that the browser vendors simply haven't spent sufficient effort to optimize these data structures yet.

I only mention this because another option that hasn't been suggested yet is using normal arrays with a single byte per element to represent the binary data. From the perspective of Javascript code (ignoring encode/decode in the user agent itself) this would be the highest performing representation until browser vendors address ImageData and ArrayBuffer performance. This would require some way of specifying that the input data to send() should be treated as binary since it would be ambiguous whether the array should be treated as 'text' or binary.
Comment 23 Joel Martin 2011-04-18 17:50:21 UTC
Followup on comment #22.

Here is a blog post with the test results for binary data handling (normal Javascript arrays, vs ImageData arrays, vs ArrayBuffer/Uint8Array): http://blog.n01se.net/?p=248
Comment 24 Yuta Kitamura 2011-04-20 06:31:42 UTC
(In reply to comment #22)
> If dynamic data-type switching is implemented, it will be important to clearly
> define when the switch happens. For example, if the UA has received two
> WebSockets messages and the handler for the first message switches the
> data-type, does the pending message get dispatched using the new type, or only
> subsequent message received by the UA. From the perspective of the Javascript
> code, clearly the second message should be the new type, but I suspect this
> adds   UA implementation complexity. I think dynamic data-type switching should
> be avoided.

I think this is actually a good point. That said, I think I'm OK with binaryResponseType proposal, provided that the spec clarifies the following points:
  - When applications are allowed to set binaryResponseType, and
  - For Blobs, what content type is specified (I assume it'll be an empty string).
Comment 25 Ian Fette [Google] 2011-04-25 17:21:57 UTC
Re: extensions, it's critical for us to at least know what extensions are in use. I don't think we need to go overboard, but I want to know e.g. if compression is enabled (if not, I will compress myself in script), if multiplexing is enabled (if not, I will not open further connections), etc.
Comment 26 Jonas Sicking (Not reading bugmail) 2011-04-25 18:57:22 UTC
Couldn't we simply require those "extensions". Is anyone planning on writing implementations that doesn't compress or that doesn't support multiplexing.

Even better would be to require them on a protocol level.
Comment 27 Ian Fette [Google] 2011-04-25 19:01:14 UTC
Well, we can certainly require them server-side, e.g. reject the handshake if the mux extension isn't present. I don't know if all browsers intend to support mux -- i certainly hope so, as it seems a lot of large services have said this is required for them, but I can only speak for Chrome.  The question arises though, let's say you get a connection that doesn't support mux. If you can't see what extensions are negotiated via js, you either on the server accept the connection and potentially many more, or you reject it and don't get to use WS at all. That seems suboptimal.
Comment 28 Jonas Sicking (Not reading bugmail) 2011-04-25 19:44:36 UTC
But why does the WebSocket protocol support mux-less or compression-less connections at all?
Comment 29 Ian Fette [Google] 2011-05-02 20:36:06 UTC
(In reply to comment #28)
> But why does the WebSocket protocol support mux-less or compression-less
> connections at all?

Because it was about the only way we could make forward progress. I would very much like to see all browsers supporting mux, yet invariably in a working group one has to make compromises to move things forward. One such compromise was to publish multiplexing as an extension / a separate RFC. Hopefully the extension mechanisms built into WebSockets are sufficient. John Tamplin here at Google has been doing a lot of work experimenting with mux as an extension.
Comment 30 Ian Fette [Google] 2011-05-02 20:38:46 UTC
Can we please decide one format or another for binary support? I don't have strong feelings either way, but we need forward progress. I was at an unrelated workshop on Thu/Fri and met with another browser vendor wanting to ship WS, and again, similar sentiments - let's just pick something and move on.

How do we get resolution?
Comment 31 Jonas Sicking (Not reading bugmail) 2011-05-02 23:27:07 UTC
I like the microsoft proposed solution of being able to set a property which controls which format all future events uses.

Performance-wise it would be nice if it was possible to set this property before opening the connection, which would mean that we have to add a separate .open method on WebSocket rather than using the constructor.

However either way I think it should be possible to set the format dynamically at any point.

However note that no matter what I think the API needs to be vendor-prefixed. Too often have we fallen into the trap of shipping unprefixed APIs that later needed fixes.
Comment 32 Takeshi Yoshino 2011-05-06 05:04:31 UTC
I'm fine with Adrian's proposal if extensions property is supported and dynamic type change (after open) is prohibited.

Once there we find some significant need for dynamic type switching, we may enable it. I think new type should be used after substitution i.e. even if there's already ArrayBuffer object prepared by UA, let UA convert it into Blob and invoke onmessage with it. This complicates UA implementation as Joel says, but looks better than the other semantics from JavaScript perspective.
Comment 33 Jonas Sicking (Not reading bugmail) 2011-05-06 09:31:45 UTC
I agree. It will definitely make implementation harder, but I think it's worth the benefit to the javascript user. Additionally, it allows switching to Blob if the application knows that the next message is going to be a very large binary. This saves memory resources which is to benefit of the browser too.
Comment 34 Robert 2011-05-10 01:10:53 UTC
Can I point out - I think you've all gone WAY too far!
Javascript doesn't handle (nor does it need it) any binary data.
I am presently sending and receiving binary data (audio and images) in base 64 as a string after JSON'ing it.
I don't have a problem with data transfer!
My only problem is with you guys chasing rainbows for an end that is never going to occur.
People need to handle JSON strings within WebSockets, it works NOW.
WE DON'T NEED BLOBs. 
Can someone give me an example of blob use for javascript that cannot be done with a JSON named string?
Comment 35 Joel Martin 2011-05-10 21:17:56 UTC
Robert,

I think you are asking for a general rationale for binary API support in WebSockets. I don't know of an existing document that answers that clearly so since I am a developer that is already using WebSockets to send/receive binary data (and since I am pining for native binary support in the API) I thought I would give it a shot.

Many browser Javascript implementations have had binary data for years in the form of Canvas ImageData arrays. Several browser already have experimental Typed Arrays to support WebGL. It is likely that some form of typed arrays will make it into official Ecmascript in the near future. Blob types are coming quickly due to work around the File and Media access APIs. So binary data types are already in Javascript and more support is coming. 

The purpose of WebSockets is to enable easy low-latency communication. As you note, binary data can already be encoded to strings and sent over the existing WebSockets API and protocol. But you can do the same with AJAX/Comet. The core reason to use WebSockets instead of existing AJAXey/long-poll mechanisms is for the significantly lower latency due to the full-duplex and low-overhead nature of WebSocket connections (it's also much simpler which is great). Enocding and decoding of binary data in Javascript adds non-trivial amounts of latency.

So ...

* binary data in Javascript is here already with more coming

* low-latency is a core driver of WebSockets

* encode/decode add latency (especially if done by Javascript code)

* developers will certainly want to send binary data over WebSockets

... enabling the WebSockets API to natively support binary data (HyBi version 07 already supports binary data) is a logical step and now is the right time to begin working on it.

A real world example that would get a huge benefit from native binary support in WebSockets is noVNC (https://github.com/kanaka/noVNC). noVNC is a VNC client that renders to Canvas and that leverages websockify to connect to a VNC server over WebSockets. For noVNC, low network latency is absolutely critical. noVNC is already quite usable (and has been intergrated into OpenStack, OpenNode, openQRM, Archipel, etc) but one of the main limiting factors is that it has to encode/decode binary data to/from base64 strings to be able to communicate with the server via websockify. Removing the string encode/decode step will bring noVNC much closer to the performance of a native VNC client.

I expect that noVNC will just use the typed array mode rather than Blob but I can certainly imagine applications that would want to treat the data as a Blob rather a binary typed array. As soon as the new binary API is available I will add support to noVNC and websockify because it will be such a big win (not even considering the bandwidth savings by not using base64).

Hopefully that answered your question.
Comment 36 Takashi Toyoshima 2011-05-11 08:06:29 UTC
These months, I found some web application developer's discussion about readyState OPEN.
So now I have two topics to discuss here.

Current spec describe on OPEN state as 'The WebSocket connection is established and communication is possible'.
Some developer misunderstand this statement as OPEN state could represent realtime connection reachability.
But actual behavior is quite different. OPEN state may mean TCP socket binded to WebSocket object is still alive, but it could not say client could communicate with server immediately. It's quite possible that intermediary firewall shutdown the connection between itself and server or any network trouble obstructs the communication.
Could we improve this description on OPEN state? It will prevent unexpected misunderstandings. This is my first suggestion.

In my understandings, if application need to check the realtime communication reachability, it's the only way to use ping-pong within application specific time intervals. I believe most applications should implement it for server pushed messages. Fortunately updated protocol spec include ping-pong frames, but the usage is not so clear now.
One idea is that browser use it implicitly to keep connection alive. It might help application developers, but browser could not handle all situations. As a result, application developers will write his own useful ping-pong.
Another idea is exporting the ping-pong protocol mechanism to API. Applications enable ping-pong with favorite timeout parameter, then browser handles ping-pong with passed parameters. If browser detect timeout on pong receiving, for example ontimeout callback event is fired. This scheme introduce a quick chance of auto reconnection to applications with simple additional code.
Comment 37 Robert 2011-05-11 22:13:27 UTC
Joel Martin,

Thank you (you should get a job in documentation writing - I'm aware google (Chrome) needs it).

Must be just my way of seeing things.

If Javascript is fast enough - you should be able to generate the data(binary) on the client end faster than sending the binary as is?
Anyway, Why can't the previous implementation go out as WS.
Then you can argue later about the Web Blob version (WB or even WSS seeing as its effectively the same!).
I would like to get our product to market now (it already runs inside chrome with the present version of WS).

We ARE NOT using the cloud for our services (on purpose - one of our selling points), so I need to have the server capable of both types.
Existing, installed, and whatever, this group settles on for the next (and probably not final) version.

NodeJS as our server running WS to clients running chrome using WS - simple! (but NO).

So yes, I have a vested interest in getting this approved, as is, - NOW.

We are using WS as the connection services for our distributed database, distributed Social Services. So, having hundreds of thousands of remote servers, all running independently, all needing updating every 2nd month with a new version of WS, no thanks.
We had figured out a way to rely on the a part of our App that would be able to test everything else against viruses etc. 
To date - it works!

Sorry - I rambled.

My background - hardware design, (PCB for micros), so I have always known what the hardware is capable of, but the programmers could never get the best out of the hardware because .....
Anyway, I found Javascript, it allows me to get what I want from the hardware (event driven) yet give a useful interface to the end user. YAH!

So I have a very different outlook.
I just happen to believe that most people are ignoring the fact that their is so much processing power at the the client end, and programmers are still ignoring it.
We have hundreds of forms in our application running in <10K lines of javascript, and not a single <form> (if that makes sense, no submitting). 
I'll get out of here now, thanks for putting up with my ramblings. 
PLEASE, just approve a (any) version of WS asap. 
good luck...
Comment 38 Joel Martin 2011-05-12 00:11:33 UTC
Robert,

I don't speak directly for any of the browser vendors, but I think I might be able to put your concerns to rest.

The binary support at the protocol level has been in the drafts for quite a while and is not controversial so it will certainly survive. Browser vendors don't necessarily have to expose the binary support in the API in order to implement more recent versions of the protocol. If the API binary support being discussed in this bug is not ready soon, the browser vendors will almost certainly still ship their next browser versions with the new HyBi protocol revision.

Binary support in the API is not going to hold back browser vendors from shipping the next protocol revision, IMO. For example, I have been testing builds of firefox-5/6 that implement HyBi-07 but not the new API (because they are waiting on a more definitive consensus here).

Firefox and Opera disabled WebSockets by default due to security concerns raised with the Hixie protocol drafts (specifically related to misbehaving intermediaries). The new HyBi protocol drafts address this issue so I expect that Mozilla and Opera will soon release versions of with WebSockets re-enabled.

Also, if you are not familiar with [web-socket-js](https://github.com/gimite/web-socket-js) you can use that as a fallback/polyfill for browsers that don't have WebSockets (or have it disabled).

In other words, the discussion here will not impact whether or not you can use WebSockets. The existing functionality of being able to send strings will be unaffected by the discussion here. If you are maintaining your own WebSockets server then you will need to update to HyBi-07 once browsers start enabling that, but that's pretty straight forwards (many servers have already done so) and you can start now because the protocol version can be determined from the handshake.
Comment 39 Simon Pieters 2011-05-25 06:45:15 UTC
(In reply to comment #31)
> I like the microsoft proposed solution of being able to set a property which
> controls which format all future events uses.
> 
> Performance-wise it would be nice if it was possible to set this property
> before opening the connection, which would mean that we have to add a separate
> .open method on WebSocket rather than using the constructor.

Wouldn't it be the same performance-wise to set the property in the CONNECTING state? Note that the state doesn't change to OPEN until the event loop has spun at the earliest.
Comment 40 Jonas Sicking (Not reading bugmail) 2011-05-25 07:37:30 UTC
Yeah, I think you can for all practical purposes get the same performance if you set the property right after opening the connection.

The thing that is worst for performance is switching from get-data-as-blob to get-data-as-arraybuffer in the case where you've already started receiving data. The reason this is particularly bad is that when in get-data-as-blob mode the implementation is likely streaming data directly to disk. If you then switch to get-data-as-arraybuffer that means that you first wrote the data to disk and then read it back into memory unnecessarily.

We could add the ability to say some thing like "give me the next message as a blob, but then switch back to arraybuffer". However I suspect that such things are overkill at this point.


Another note: Do we only want to allow receiving binary messages as Blobs? XHR Level 2 for example allows receiving any response as a Blob. And Blobs do have some features for reading text files (FileReader.readAsText).

One possibility is that text messages always arrive as strings and binary messages as ArrayBuffers. But at any point you can say that you want to start receiving messages in the form of Blobs which would affect both text and binary messages.
Comment 41 Ian 'Hixie' Hickson 2011-05-27 23:34:39 UTC
Did all the things I set out in comment 0 except the extensions attribute, which is blocked on an issue in the protocol spec. I'll update that in response to Ian's reply to my mail to him about it.
Comment 42 Takeshi Yoshino 2011-06-14 07:47:29 UTC
Hi, I checked the latest draft (Editor's Draft 13 June 2011), and then had some questions.

----

> Each string in the array is a subprotocol name. The connection will only be established ...

what "reports" actually means? Maybe you're going to use _Subprotocol in Use_ here in the next draft?

----

> The connection will only be established if the server reports ...

What if the protocols is an empty array (so, no Sec-WebSocket-Protocol was sent in client's opening handshake)? I think _Subprotocol in Use_ == null is expected. Could you add a text to handle this case explicitly when you update the draft next time?

In HyBi thread http://www.ietf.org/mail-archive/web/hybi/current/msg07448.html I listed client's behaviors I think reasonable. Your current text seems to cover most of my suggestions, but some remaining.

----

> The subprotocol names must all be non-empty ASCII ...

Wire protocol spec http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-09 forbids some characters other than SP ("separators" defined in RFC 2616). Please make them consistent. I think we should align them to "token" of RFC 2616.

---

> 4. If any of the values in protocols occur more ...

ditto about allowed characters.

Say, "any of values must be non empty" too.