New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Would a "closing" connection state be of any use? #240
Comments
As suggested in #239 (comment) |
In case of WebSocket, for example, when a client calls |
Thanks @tomoyukilabs, Your comment raises an important point, which I overlooked in my review of PR #239: it is good practice to continue listening to data as long as the underlying connection has not been closed. For instance, the Web Socket Protocol (TCP and WebRTC data channels have similar expectations, I believe) says:
In particular, the From an app perspective, it feels strange to be able to receive a message after calling @mfoltzgoogle that is how I had formulated my initial PR #238 (waiting for a signal from the other side becore triggering the @tomoyukilabs, back to the notion of It seems to me that, for all practical purpose, an app would only need to have code such as |
@tidoust Although
Yes, SCTP (underlying transport protocol of WebRTC data channel) also says:
|
To see actual behavior of window.addEventListener('load', function() {
var state = ['CONNECTING', 'OPEN', 'CLOSING', 'CLOSED'];
var log = document.getElementById('log');
var ws = new WebSocket('wss://websocket-server/path');
ws.addEventListener('open', function() {
log.innerHTML += 'WebSocket: OPEN<br>';
// close WebSocket connection during receiving message from a server
setTimeout(function() {
log.innerHTML += "WebSocket: close()<br>";
ws.close();
}, 50);
});
ws.addEventListener('message', function() {
log.innerHTML += 'WebSocket: message received (readyState === "' + state[ws.readyState] + '")<br>';
});
ws.addEventListener('close', function() {
log.innerHTML += 'WebSocket: CLOSED<br>';
});
}); This example assumes that the WebSocket server would send a large message to the client as soon as the connection would have been established. I tried this example, and several browsers such as Chrome, Firefox, Edge and IE11 showed the same result like below:
This result indicates that WebSocket client in most browsers would discard messages sent from a server after calling On the other hand, Safari showed a different result like below:
|
@tomoyukilabs that's very interesting, thanks for the investigation! If I understand the specs, example (note the server seems down), and results properly, only Safari has the right behavior according to specs. All other browsers close the WebSocket too early. Now, when one looks at it from an application perspective, it seems more straightforward not to have to code the logic needed to handle a message received after calling I'll try to create a similar test example for WebRTC. |
@tidoust Sorry, I found I had misconfigured my server. Now I have fixed it and the server is working now. By the way, I tried to read the WebSocket interface spec, but I have not found any description about behavior in case of receiving messages during closing handshake, yet. The spec does not seem to say explicitly either such messages would be discarded or a
Thanks so much! |
@tomoyukilabs Thanks, your example works fine now! I realize that I misread the the WebSocket interface spec and that it explicitly instructs user agents to discard messages received after a call to
(Calling Thus I was wrong: your tests suggest that all tested Web browsers behave according to spec, except Safari. I also misread the WebSocket protocol as it does not suggest that an on-going transmission should be finished but rather says "An endpoint MAY delay sending a Close frame until its current message is sent [...] However, there is no guarantee that the endpoint that has already sent a Close frame will continue to process data": The initial questions remain, though:
Running your example clearly shows that user agents wait for the server ack before they transition the WebSocket connection to "closed" (as specified). Knowing that there is still a pending connection encourages the app to wait in situations where it wants to re-connect to the WebSocket server, perhaps? |
@tidoust Thanks for clarification. It turns out I also misunderstood the task during closing handshake.
At least, such a situation may imply that the app tries to close WebSocket connection when the server has been still in the middle of sending something to the app, or that the server might be down or still continue unexpected data transfer. One of best practices for the former case seems to be that the server should notify the app of server's intention to send any data beforehand, within application-level implementation. Otherwise, the server can abort sending data as soon as it has received a close frame from the app. (Note: this may require frame-level handling for the server.) Of course, the app may choose to re-connect and ask the server to send the same data again. In my opinion, exposing the |
Trying to generalize this beyond WebSockets a bit, the use case for closing seems to be the following:
This could be useful, perhaps B would transmit some state to help A reconnect in the future. However, there's no guarantee that A will receive them, in case the connection is closed by navigation, termination, or error (i.e., a reason other than Also, B could be misbehaving: spamming A with messages and ignoring the request to close. We would probably need to specify that the close event must happen within a reasonable time, even if there are pending messages. |
@mfoltzgoogle wrote:
Despite what I thought initially, at the API level in both WebRTC and WebSockets, A cannot receive these final messages even if it wants to (state is switched to So, for me, the main use case for closing seems to be for debugging. In the WebSocket case, this gives the web app a way to detect that the WebSocket server is misbehaving or taking an unusual amount of time... but that could well be done by the user agent itself without exposing this transient state (e.g. through warnings in the console). I'm not convinced this warrants the introduction of a |
If that's true, then I agree that a closing state doesn't seem warranted. It seems like it doesn't add any functionality that either connected party could take advantage of. |
Both WebSockets and WebRTC data channels switch to a
closing
state when the closing procedure is started. The state switches toclosed
at the end of the closing handshake, in other words when the underlying protocol triggers some signal that the connection should be regarded as closed.The
closing
state makes sense from a procedural perspective (this matches how the user agent is going to handle the closing process). I do not know why this state is exposed to Web apps, though. It seems to me that all use cases I can think of would equally work with only theclosed
state that we have in the Presentation API.However, the rationale that led to the
closing
state in WebSockets and WebRTC data channels probably applies toPresentationConnection
as well. So, question is: does anyone know that rationale?The text was updated successfully, but these errors were encountered: