<br><br><div class="gmail_quote">On Mon, Jul 6, 2009 at 9:30 PM, Ian Hickson <span dir="ltr">&lt;<a href="mailto:ian@hixie.ch">ian@hixie.ch</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div class="it">On Fri, 26 Jun 2009, James Robinson wrote:<br>
&gt;<br>
&gt; 0) postMessage() looks as if it is intended to mimic<br>
</div>&gt; MessagePort.postMessage(), but the arguments and error conditions are<br>
<div class="it">&gt; different.  While it would be conceptually nice to treat a web socket in<br>
&gt; the same way as a message port, it&#39;s not possible to treat the two<br>
&gt; postMessage() functions in the same way.  I&#39;d recommend the WebSocket<br>
&gt; version be renamed to something like &quot;send()&quot; to avoid confusion and<br>
&gt; false expectations.<br>
<br>
</div>Fair enough. Done.<br>
<div class="it"><br>
<br>
<br>
&gt; There&#39;s similar oddness with receiving events that satisfy the MessageEvent<br>
&gt; interface - since all fields except &#39;data&#39; will necessarily be invalid I<br>
&gt; don&#39;t see the value in receiving something more complex.<br>
<br>
</div>I would like to avoid introducing four different event types for the four<br>
different types of &#39;message&#39; events being introduced, which is why I<br>
overloaded the same interface for all four. I don&#39;t think it&#39;s a problem.<br>
<div class="it"><br>
<br>
&gt; 1) The &#39;readyState&#39; attribute can never actually be used by an application<br>
&gt; and is redundant.<br>
&gt;<br>
&gt; Initially, the &#39;readyState&#39; attribute is set to CONNECTING, but while<br>
&gt; the object is in this state the user is not permitted to interact with<br>
&gt; the WebSocket in any way.  The only useful thing that a user could do is<br>
&gt; set event handlers and wait for the &#39;open&#39; event to fire.  When the<br>
&gt; WebSocket becomes connected, the readyState becomes 1 and the &#39;open&#39;<br>
&gt; event is fired. Once the WebSocket is open, the spec states that<br>
&gt; whenever the connection is closed the readyState changes to CLOSED and a<br>
</div>&gt; &#39;close&#39; event is enqueued. However, users can&#39;t usefully check the<br>
<div class="it">&gt; readyState to see if the WebSocket is still open because there are not<br>
&gt; and cannot be any synchronization guarantees about when the WebSocket<br>
</div><div class="it">&gt; may close.  A user will have to wrap all calls to postMessage() (or<br>
&gt; send() if the function is renamed) in a try/catch block in order to<br>
&gt; handle INVALID_STATE_ERRs.  Once the &#39;close&#39; event has been received the<br>
&gt; readyState attribute is useless since the state of the WebSocket is<br>
&gt; known and can never change.<br>
&gt;<br>
&gt; I think &#39;readyState&#39; should just go away since an application will have<br>
&gt; to keep track of state updates through the fired events and use<br>
&gt; try/catch blocks around all API calls anyway.<br>
<br>
</div>The attribute is mostly present for debugging purposes. I wouldn&#39;t expect<br>
anyone to actually use it for production work.<br>
<div class="it"><br>
<br>
On Fri, 26 Jun 2009, Drew Wilson wrote:<br>
&gt;<br>
&gt; Yes, but the &quot;closed&quot; state of a given WebSocket doesn&#39;t have to exactly<br>
&gt; match the state of the underlying TCP connection, in the same way that<br>
&gt; document.cookies doesn&#39;t exactly match the current set of cookies that<br>
&gt; the network stack may be tracking (they can differ when HTTP responses<br>
&gt; are received in the background while JS is executing).<br>
&gt;<br>
&gt; So if the remote server closes the TCP connection, it generates a<br>
&gt; &quot;close&quot; event which marks the WebSocket as closed. It means that you<br>
&gt; could have a situation where you post messages to a WebSocket which<br>
&gt; aren&#39;t received by the server because the connection is closed, but<br>
&gt; that&#39;s true regardless due to the asynchronous nature of the networking<br>
&gt; protocol.<br>
<br>
</div>I&#39;ve changed the spec to not throw an exception on send() if the<br>
connection is closed.<br>
<div class="it"><br>
<br>
On Fri, 26 Jun 2009, Kelly Norton wrote:<br>
&gt;<br>
&gt; One thing about postMessage that I&#39;m curious about. Since it has to<br>
&gt; report failure synchronously by throwing an INVALID_STATE_ERR, that<br>
&gt; seems to imply that all data must be written to a socket before<br>
&gt; returning and cannot be asynchronously delivered to an I/O thread<br>
&gt; without adding some risk of silently dropping messages. Seems like the<br>
&gt; right choice would be to allow outbound messages to drop, which would<br>
&gt; mean that developers would be forced to do their own handshaking.<br>
<br>
</div>send() doesn&#39;t report I/O errors, it only throws an exception if the<br>
connection isn&#39;t open yet (and previously, if the connection had died<br>
prior to it being called, though that is no longer the case), or if the<br>
input is invalid.<br>
<div class="it"><br>
<br>
&gt; I&#39;m also not sure there is good coverage of error conditions in the<br>
&gt; spec. The only methods of error notification are exceptions in<br>
&gt; postMessage and onclose.<br>
<br>
</div>In fact, only onclose actually reports an error; the exception from send()<br>
now only reports a misuse of the API, not a network error.<br>
<div class="it"><br>
<br>
&gt; I had assumed that a WebSocket that fails to connect would invoke<br>
&gt; onclose asynchronously, but I didn&#39;t see that in the spec.<br>
<br>
</div>It&#39;s there, though subtle. :-)<br>
<br>
The constructor in the API spec invokes the &quot;Establish a Web Socket<br>
connection&quot; algorithm from the protocol spec. That algorithm then invokes<br>
the &quot;fail the Web Socket connection&quot; algorithm upon failure, and that<br>
algorithm says to invoke the &quot;close the Web Socket connection&quot; algorithm,<br>
and that algorithm says that this means that &quot;Web Socket connection is<br>
closed&quot;, and the API spec says &quot;When the Web Socket connection is closed,<br>
the readyState attribute&#39;s value must be changed to CLOSED (2), and the<br>
<div class="it">user agent must queue a task to fire a simple event called close at the<br>
WebSocket object&quot;.<br>
<br>
</div>I&#39;ve added a note that says this.<br>
<div class="it"><br>
<br>
&gt; Without that you don&#39;t even have the ability to know if a<br>
&gt; socket failed to establish a connection (short of readyState polling).<br>
&gt; The spec also doesn&#39;t indicate that the readyState should transition to<br>
&gt; CLOSED on connection failure.<br>
<br>
</div>This is part of the same sequence of events as described above.<br>
<div class="it"><br>
<br>
On Fri, 26 Jun 2009, Kelly Norton wrote:<br>
&gt;<br>
&gt; Doesn&#39;t it seem strange that disconnect() causes an onclose event to be<br>
&gt; dispatched? Should the method not be close() to be consistent with<br>
&gt; open(), onopen, onclose?<br>
<br>
</div>I&#39;ve renamed disconnect() to close() in both EventSource and WebSocket.<br>
<br>
<br>
On Fri, 26 Jun 2009, Michael Nordman wrote:<br>
&gt;<br>
&gt; Does disconnect() attempt to flush pending messages or drop them? There<br>
<div class="it">&gt; isn&#39;t a way to determine if the WebSocket is successfully sending the<br>
&gt; postMessage data? For all the caller knows, its just backing up and not<br>
&gt; going anywhere.<br>
&gt;<br>
</div><div class="it">&gt; Something that might add value is an onmessagesent event that fires<br>
&gt; after a postMessage has put the bits on the wire.<br>
<br>
</div>If you want acknowledgements, implement app-level acks -- in practice,<br>
there&#39;s not much difference between hitting the network or not, if the<br>
other side hasn&#39;t yet received the packets.<br>
<div class="it"><br>
<br>
&gt; postMessage() may want another exception condition... &#39;too much data<br>
&gt; pending exception&#39;... consider calling postMessage in a while(true)<br>
&gt; loop... at some point the system is going to have to give up queing the<br>
&gt; data if its not actually making its way out on the wire.<br>
<br>
</div>The spec doesn&#39;t specify how UAs are to handle hitting hardware<br>
limitations or system limitations, because it&#39;s often difficult to truly<br>
control how those cases are handled.<br>
<div class="it"><br>
<br>
On Fri, 26 Jun 2009, James Robinson wrote:<br>
&gt;<br>
&gt; Not changing variables out from under executing JavaScript makes a lot<br>
&gt; of sense, but if that was the case then it&#39;s not clear when the<br>
&gt; readyState could be updated.  The spec states &quot;When the *Web Socket<br>
</div>&gt; connection is closed*, the readyState attribute&#39;s value must be changed<br>
<div class="it">&gt; to CLOSED (2), and the user agent must queue a task to fire a simple<br>
&gt; event called close at the WebSocket object.&quot; If the browser cannot<br>
&gt; mutate the readyState until JavaScript stops running then it would<br>
&gt; either have to either enqueue a second task to change readyState at some<br>
&gt; point in the future or set the readyState right before dispatching the<br>
&gt; &#39;close&#39; event.  The latter would be much nicer to implement - but then<br>
&gt; it does make the readyState completely useless as it would always be<br>
&gt; exactly equivalent to the last event that was fired on a given<br>
&gt; WebSocket.<br>
<br>
</div>I&#39;ve left it as is (the attribute changes on the fly), which is possibly<br>
risky, but more consistent with how such attributes are handled in<br>
general.<br>
<div class="it"><br>
<br>
&gt; I think a better way to do error handling is to have an asynchronous<br>
&gt; onerror callback or event when the browser notes that a message did not<br>
&gt; make it to the other side.<br>
<br>
</div>The client can&#39;t really always know this anyway. I think it&#39;s better to do<br>
app-level acking if you care enough.<br>
<div class="it"><br>
<br>
On Fri, 26 Jun 2009, James Robinson wrote:<br>
&gt;<br>
&gt; The concept of a port being in a closed state is not very well defined -<br>
&gt; if the state means only the readyState status, then when can the state<br>
&gt; legally be updated?  If it has some meaning closer to the state of the<br>
&gt; underlying connection, then it can&#39;t be queried synchronously without<br>
&gt; very expensive synching to the I/O thread or process.<br>
&gt;<br>
</div><div class="it">&gt; Forcing applications to build their own send/ack functionality would be<br>
&gt; pretty tragic considering that WebSockets are built on top of TCP.<br>
<br>
</div>If we had access to the underlying TCP packets, I guess we could return a<br>
number with each send() and have some way to query the number of the<br>
mesage that the most recent packet that got all the way to other side<br>
contained, but in practice I don&#39;t think that implementations are always<br>
going to have access to that, and also it&#39;s not just that the other stack<br>
got the message that matters, but that the remote server actually got the<br>
messages and processed it.<br>
<div class="it"><br>
<br>
On Fri, 26 Jun 2009, Michael Nordman wrote:<br>
&gt;<br>
&gt; If you&#39;re uploading a large data set incrementally across many distinct<br>
&gt; postMessage calls (perhaps to leave room for other control messages<br>
&gt; interspersed amoungst them, or to present progress info), how do you<br>
&gt; know when to queue more data to be sent.<br>
<br>
</div>I think when we add support for file upload, we&#39;ll make it so that it<br>
automagically supports this case. That is, you&#39;ll say &quot;upload this file in<br>
small bits&quot; and then if you later say &quot;send this text message&quot;, the text<br>
message will be sent before any pending file bits. We can use a separate<br>
type of packet in the WebSocket stream to do this.</blockquote><div><br></div><div>Sounds like that would require a protocol change. Is the message framing spec&#39;d in such a way that a new &#39;packet type&#39; can be introduced in a backward compatible fashion? </div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><br>
<font color="#888888"><br>
--<br>
Ian Hickson               U+1047E                )\._.,--....,&#39;``.    fL<br>
<a href="http://ln.hixie.ch/" target="_blank">http://ln.hixie.ch/</a>       U+263A                /,   _.. \   _\  ;`._ ,.<br>
Things that are impossible just take longer.   `._.-(,_..&#39;--(,_..&#39;`-.;.&#39;<br>
</font></blockquote></div><br>