From e9dfcc4ee9ea57cc1e3bb84b6c95cf6084fd12f6 Mon Sep 17 00:00:00 2001 From: Anmol Sethi <hi@nhooyr.io> Date: Fri, 17 May 2019 09:00:53 -0400 Subject: [PATCH] Improve Close UX Closes #78 --- websocket.go | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/websocket.go b/websocket.go index 912508d..c0737ca 100644 --- a/websocket.go +++ b/websocket.go @@ -5,6 +5,7 @@ import ( "context" "fmt" "io" + "os" "runtime" "sync" "sync/atomic" @@ -353,6 +354,12 @@ func (c *Conn) writePong(p []byte) error { // Close closes the WebSocket connection with the given status code and reason. // It will write a WebSocket close frame with a timeout of 5 seconds. +// The connection can only be closed once. Additional calls to Close +// are no-ops. +// The maximum length of reason must be 125 bytes otherwise an internal +// error will be sent to the peer. For this reason, you should avoid +// sending a dynamic reason. +// Close will unblock all goroutines interacting with the connection. func (c *Conn) Close(code StatusCode, reason string) error { err := c.exportedClose(code, reason) if err != nil { @@ -372,17 +379,14 @@ func (c *Conn) exportedClose(code StatusCode, reason string) error { // Definitely worth seeing what popular browsers do later. p, err := ce.bytes() if err != nil { + fmt.Fprintf(os.Stderr, "failed to marshal close frame: %v\n", err) ce = CloseError{ Code: StatusInternalError, } p, _ = ce.bytes() } - cerr := c.writeClose(p, ce) - if err != nil { - return err - } - return cerr + return c.writeClose(p, ce) } func (c *Conn) writeClose(p []byte, cerr CloseError) error { -- GitLab