@@ -16,84 +16,81 @@ go get nhooyr.io/websocket@master
16
16
17
17
## Features
18
18
19
+ - HTTP/2 over WebSocket's support
19
20
- Full support of the WebSocket protocol
21
+ - Only depends on the stdlib
20
22
- Simple to use because of the minimal API
21
23
- Uses the context package for cancellation
22
24
- Uses net/http's Client to do WebSocket dials
23
25
- 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
26
27
- WASM support
27
28
28
29
## Example
29
30
30
31
### Server
31
32
32
33
``` 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
+ )
61
38
if err != nil {
62
- log.Fatalf (" failed to listen and serve: %v " , err)
39
+ log.Printf (" server handshake failed: %v " , err)
40
+ return
63
41
}
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 , " " )
70
43
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 )
75
45
defer cancel ()
76
46
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" ,
82
49
}
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)
87
51
if err != nil {
88
- log.Fatalf (" failed to read json: %v " , err)
52
+ log.Printf (" failed to write json: %v " , err)
53
+ return
89
54
}
90
55
91
- log.Printf (" received %v " , v)
56
+ log.Printf (" wrote %v " , v)
92
57
93
58
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)
94
63
}
95
64
```
96
65
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
+
97
94
See [ example_test.go] ( example_test.go ) for more examples.
98
95
99
96
## Design considerations
@@ -105,24 +102,28 @@ See [example_test.go](example_test.go) for more examples.
105
102
- net.Conn is never exposed as WebSocket's over HTTP/2 will not have a net.Conn.
106
103
- Functional options make the API very clean and easy to extend
107
104
- Compression is very useful for JSON payloads
108
- - Protobuf and JSON helpers make code terse
105
+ - JSON helpers make code terse
109
106
- Using net/http's Client for dialing means we do not have to reinvent dialing hooks
110
107
and configurations. Just pass in a custom net/http client if you want custom dialing.
111
108
112
109
## Comparison
113
110
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
+
114
115
### gorilla/websocket
115
116
116
117
https://github.com/gorilla/websocket
117
118
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
119
120
has 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
121
122
[ nhooyr/websocket] ( godoc.org/github.com/nhooyr/websocket ) side by side with
122
123
[ gorilla/websocket] ( godoc.org/github.com/gorilla/websocket ) .
123
124
124
125
The 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.
126
127
127
128
### x/net/websocket
128
129
@@ -137,12 +138,12 @@ See https://github.com/golang/go/issues/18152
137
138
https://github.com/gobwas/ws
138
139
139
140
This 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.
141
142
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
144
145
I could into nhooyr/websocket.
145
146
146
147
If you want a library that gives you absolute control over everything, this is the library,
147
148
but 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