Skip to content

Simplify closing handshake#914

Merged
lpinca merged 1 commit intomasterfrom
simplify/closing-handshake
Jan 3, 2017
Merged

Simplify closing handshake#914
lpinca merged 1 commit intomasterfrom
simplify/closing-handshake

Conversation

@lpinca
Copy link
Copy Markdown
Member

@lpinca lpinca commented Nov 26, 2016

Currently the close handshake works like this when initiated from the server:

        SERVER                                 CLIENT


+--------------------+
|ws.close()          |
|readyState = CLOSING|
+--------------------+
           |            +-----------+
           +----------->|close frame|-------------+
                        +-----------+             v
                                       +--------------------+
                                       |closeReceived = true|
                                       |ws.close()          |
                                       |readyState = CLOSING|
                                       +--------------------+
                        +-----------+             |
           +------------|close frame|<------------+
           v            +-----------+
+--------------------+
|closeReceived = true|
|ws.close()          |
|ws.terminate()      |
|socket.end()        |
+--------------------+
           |              +-------+
           +------------->|TCP FIN|---------------+
                          +-------+               v
                                        +-------------------+
                                        |readyState = CLOSED|
                                        |ws.emit('close')   |
                                        |socket.end()       |
                                        +-------------------+
                          +-------+               |
           +--------------|TCP FIN|<--------------+
           |              +-------+
           v
 +-------------------+
 |readyState = CLOSED|
 |ws.emit('close')   |
 +-------------------+

and like this when initiated from the client:

        CLIENT                                 SERVER


+--------------------+
|ws.close()          |
|readyState = CLOSING|
+--------------------+
           |            +-----------+
           +----------->|close frame|-------------+
                        +-----------+             v
                                       +--------------------+
                                       |closeReceived = true|
                                       |ws.close()          |
                                       |readyState = CLOSING|
                                       |ws.terminate()      |
                                       |socket.end()        |
                                       +--------------------+
                   +---------------------+        |
           +-------|close frame + TCP FIN|<-------+
           v       +---------------------+
+--------------------+
|closeReceived = true|
|ws.close()          |
|readyState = CLOSED |
|ws.emit('close')    |
|socket.end()        |
+--------------------+
           |              +-------+
           +------------->|TCP FIN|---------------+
                          +-------+               v
                                        +-------------------+
                                        |readyState = CLOSED|
                                        |ws.emit('close')   |
                                        +-------------------+

This patch uniforms the behavior making a close initiated by the server work in the same way of a close initiated by the client.

After reading https://tools.ietf.org/html/rfc6455#section-1.4 and https://tools.ietf.org/html/rfc6455#section-7, I think this is correct.

I have some doubts on this section which is why the close handshake is currently implemented in this way for the server but I also checked other implementations for Node.js and they use the same procedure for both client and server as proposed in this patch.

@lpinca
Copy link
Copy Markdown
Member Author

lpinca commented Nov 26, 2016

cc: @nkzawa

@lpinca
Copy link
Copy Markdown
Member Author

lpinca commented Nov 27, 2016

I guess the question to answer is:

Is there any advantage on calling socket.end() first on the server and then on the client when a close procedure is initiated by the server?

I don't know much about low level networking so if someone could shed some light on this, it would be great.

@lpinca lpinca force-pushed the simplify/closing-handshake branch from f6237a9 to 4324f4b Compare November 27, 2016 11:24
@lpinca lpinca force-pushed the simplify/closing-handshake branch 5 times, most recently from a6f1e52 to 141bc9c Compare December 20, 2016 11:49
@lpinca lpinca force-pushed the simplify/closing-handshake branch from 141bc9c to d9651aa Compare December 23, 2016 09:12
@lpinca
Copy link
Copy Markdown
Member Author

lpinca commented Jan 1, 2017

@websockets/admin any thoughts on this?

@lpinca lpinca merged commit 623872f into master Jan 3, 2017
@lpinca lpinca deleted the simplify/closing-handshake branch January 3, 2017 07:24
@citrusjunoss
Copy link
Copy Markdown

When my client is Node and the server is Java(Netty), can it work?

@lpinca
Copy link
Copy Markdown
Member Author

lpinca commented Apr 24, 2019

@citrusjunoss yes.

@citrusjunoss
Copy link
Copy Markdown

@citrusjunoss yes.

But the server does not receive any data when I call the close method

@lpinca
Copy link
Copy Markdown
Member Author

lpinca commented Apr 24, 2019

It should receive a close frame. If you don't specify a close code, it will be something like this:

88 80 45 68 03 77

The last 4 bytes are random (the mask). You can check this with wireshark if you have no access to the TCP socket.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants