diff --git a/example_test.go b/example_test.go index 57f0aa5ee072d069d9e39e505c3d140273d20c6a..bc10209e417fc2625b7bd9af059c43f142218e5a 100644 --- a/example_test.go +++ b/example_test.go @@ -59,3 +59,45 @@ func ExampleDial() { c.Close(websocket.StatusNormalClosure, "") } + +func ExampleWriteOnly() { + fn := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + c, err := websocket.Accept(w, r, websocket.AcceptOptions{}) + if err != nil { + log.Println(err) + return + } + defer c.Close(websocket.StatusInternalError, "the sky is falling") + + ctx, cancel := context.WithTimeout(r.Context(), time.Minute*10) + defer cancel() + + go func() { + defer cancel() + _, _, err := c.Reader(ctx) + if err == nil { + c.Close(websocket.StatusPolicyViolation, "server doesn't accept data messages") + } + }() + + t := time.NewTicker(time.Second * 30) + defer t.Stop() + + for { + select { + case <-ctx.Done(): + c.Close(websocket.StatusNormalClosure, "") + return + case <-t.C: + err = wsjson.Write(ctx, c, "hi") + if err != nil { + log.Println(err) + return + } + } + } + }) + + err := http.ListenAndServe("localhost:8080", fn) + log.Fatal(err) +} diff --git a/websocket.go b/websocket.go index 375685e75c9c865d434c9aae76d77c4c734bfb63..bd087d51cae3110a4680634c74a55bde32217e39 100644 --- a/websocket.go +++ b/websocket.go @@ -21,6 +21,9 @@ import ( // All methods may be called concurrently except for Reader, Read // and SetReadLimit. // +// You must always read from the connection. Otherwise control +// frames will not be handled. See the docs on Reader. +// // Please be sure to call Close on the connection when you // are finished with it to release the associated resources. type Conn struct { @@ -299,7 +302,7 @@ func (c *Conn) handleControl(ctx context.Context, h header) error { // You must read from the connection for close frames to be read. // If you do not expect any data messages from the peer, just call // Reader in a separate goroutine and close the connection with StatusPolicyViolation -// when it returns. Example at // TODO +// when it returns. See the WriteOnly example. // // Only one Reader may be open at a time. //