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