@@ -16,84 +16,81 @@ go get nhooyr.io/websocket@master
1616
1717## Features
1818
19+ - HTTP/2 over WebSocket's support
1920- Full support of the WebSocket protocol
21+ - Only depends on the stdlib
2022- Simple to use because of the minimal API
2123- Uses the context package for cancellation
2224- Uses net/http's Client to do WebSocket dials
2325- Compression of text frames larger than 1024 bytes by default
24- - Highly optimized
25- - API will transparently work with WebSockets over HTTP/2
26+ - Highly optimized where it matters
2627- WASM support
2728
2829## Example
2930
3031### Server
3132
3233``` go
33- func main () {
34- fn := http.HandlerFunc (func (w http.ResponseWriter , r *http.Request ) {
35- c , err := websocket.Accept (w, r,
36- websocket.AcceptSubprotocols (" test" ),
37- )
38- if err != nil {
39- log.Printf (" server handshake failed: %v " , err)
40- return
41- }
42- defer c.Close (websocket.StatusInternalError , " " )
43-
44- ctx , cancel := context.WithTimeout (r.Context (), time.Second *10 )
45- defer cancel ()
46-
47- v := map [string ]interface {}{
48- " my_field" : " foo" ,
49- }
50- err = websocket.WriteJSON (ctx, c, v)
51- if err != nil {
52- log.Printf (" failed to write json: %v " , err)
53- return
54- }
55-
56- log.Printf (" wrote %v " , v)
57-
58- c.Close (websocket.StatusNormalClosure , " " )
59- })
60- err := http.ListenAndServe (" localhost:8080" , fn)
34+ fn := http.HandlerFunc (func (w http.ResponseWriter , r *http.Request ) {
35+ c , err := websocket.Accept (w, r,
36+ websocket.AcceptSubprotocols (" test" ),
37+ )
6138 if err != nil {
62- log.Fatalf (" failed to listen and serve: %v " , err)
39+ log.Printf (" server handshake failed: %v " , err)
40+ return
6341 }
64- }
65- ```
66-
67- For a production quality example that shows off the low level API, see the echo example on the [ godoc] ( https://godoc.org/nhooyr.io/websocket#Accept ) .
68-
69- ### Client
42+ defer c.Close (websocket.StatusInternalError , " " )
7043
71- ``` go
72- func main () {
73- ctx := context.Background ()
74- ctx , cancel := context.WithTimeout (ctx, time.Second *10 )
44+ ctx , cancel := context.WithTimeout (r.Context (), time.Second *10 )
7545 defer cancel ()
7646
77- c , _ , err := websocket.Dial (ctx, " ws://localhost:8080" ,
78- websocket.DialSubprotocols (" test" ),
79- )
80- if err != nil {
81- log.Fatalf (" failed to ws dial: %v " , err)
47+ v := map [string ]interface {}{
48+ " my_field" : " foo" ,
8249 }
83- defer c.Close (websocket.StatusInternalError , " " )
84-
85- var v interface {}
86- err = websocket.ReadJSON (ctx, c, v)
50+ err = websocket.WriteJSON (ctx, c, v)
8751 if err != nil {
88- log.Fatalf (" failed to read json: %v " , err)
52+ log.Printf (" failed to write json: %v " , err)
53+ return
8954 }
9055
91- log.Printf (" received %v " , v)
56+ log.Printf (" wrote %v " , v)
9257
9358 c.Close (websocket.StatusNormalClosure , " " )
59+ })
60+ err := http.ListenAndServe (" localhost:8080" , fn)
61+ if err != nil {
62+ log.Fatalf (" failed to listen and serve: %v " , err)
9463}
9564```
9665
66+ For a production quality example that shows off the low level API, see the echo example on the [ godoc] ( https://godoc.org/nhooyr.io/websocket#Accept ) .
67+
68+ ### Client
69+
70+ ``` go
71+ ctx := context.Background ()
72+ ctx , cancel := context.WithTimeout (ctx, time.Second *10 )
73+ defer cancel ()
74+
75+ c , _ , err := websocket.Dial (ctx, " ws://localhost:8080" ,
76+ websocket.DialSubprotocols (" test" ),
77+ )
78+ if err != nil {
79+ log.Fatalf (" failed to ws dial: %v " , err)
80+ }
81+ defer c.Close (websocket.StatusInternalError , " " )
82+
83+ var v interface {}
84+ err = websocket.ReadJSON (ctx, c, v)
85+ if err != nil {
86+ log.Fatalf (" failed to read json: %v " , err)
87+ }
88+
89+ log.Printf (" received %v " , v)
90+
91+ c.Close (websocket.StatusNormalClosure , " " )
92+ ```
93+
9794See [ example_test.go] ( example_test.go ) for more examples.
9895
9996## Design considerations
@@ -105,24 +102,28 @@ See [example_test.go](example_test.go) for more examples.
105102- net.Conn is never exposed as WebSocket's over HTTP/2 will not have a net.Conn.
106103- Functional options make the API very clean and easy to extend
107104- Compression is very useful for JSON payloads
108- - Protobuf and JSON helpers make code terse
105+ - JSON helpers make code terse
109106- Using net/http's Client for dialing means we do not have to reinvent dialing hooks
110107 and configurations. Just pass in a custom net/http client if you want custom dialing.
111108
112109## Comparison
113110
111+ While I believe nhooyr/websocket has a better API than existing libraries,
112+ both gorilla/websocket and gobwas/ws were extremely useful in implementing the
113+ WebSocket protocol correctly so big thanks to the authors of both.
114+
114115### gorilla/websocket
115116
116117https://github.com/gorilla/websocket
117118
118- This package is the community standard but it is very old and over timennn
119+ This package is the community standard but it is very old and over time
119120has accumulated cruft. There are many ways to do the same thing and the API
120- overall is just not very clear. Just compare the godoc of
121+ is not clear. Just compare the godoc of
121122[ nhooyr/websocket] ( godoc.org/github.com/nhooyr/websocket ) side by side with
122123[ gorilla/websocket] ( godoc.org/github.com/gorilla/websocket ) .
123124
124125The API for nhooyr/websocket has been designed such that there is only one way to do things
125- and with HTTP/2 in mind which makes using it correctly and safely much easier.
126+ which makes using it correctly and safely much easier.
126127
127128### x/net/websocket
128129
@@ -137,12 +138,12 @@ See https://github.com/golang/go/issues/18152
137138https://github.com/gobwas/ws
138139
139140This library has an extremely flexible API but that comes at the cost of usability
140- and clarity. Its just not clear how to do things in a safe manner.
141+ and clarity. Its not clear what the best way to do anything is.
141142
142- This library is fantastic in terms of performance though . The author put in significant
143- effort to ensure its speed and I have tried to apply as many of its teachings as
143+ This library is fantastic in terms of performance. The author put in significant
144+ effort to ensure its speed and I have applied as many of its optimizations as
144145I could into nhooyr/websocket.
145146
146147If you want a library that gives you absolute control over everything, this is the library,
147148but for most users, the API provided by nhooyr/websocket will definitely fit better as it will
148- be just as performant but much easier to use.
149+ be just as performant but much easier to use correctly .
0 commit comments