|
1 | 1 | # websocket
|
2 | 2 |
|
3 |
| -[](https://pkg.go.dev/nhooyr.io/websocket) |
4 |
| -[](https://nhooyr.io/websocket/coverage.html) |
5 |
| - |
6 |
| -websocket is a minimal and idiomatic WebSocket library for Go. |
7 |
| - |
8 |
| -## Install |
9 |
| - |
10 |
| -```sh |
11 |
| -go get nhooyr.io/websocket |
12 |
| -``` |
13 |
| - |
14 |
| -## Highlights |
15 |
| - |
16 |
| -- Minimal and idiomatic API |
17 |
| -- First class [context.Context](https://blog.golang.org/context) support |
18 |
| -- Fully passes the WebSocket [autobahn-testsuite](https://github.com/crossbario/autobahn-testsuite) |
19 |
| -- [Zero dependencies](https://pkg.go.dev/nhooyr.io/websocket?tab=imports) |
20 |
| -- JSON helpers in the [wsjson](https://pkg.go.dev/nhooyr.io/websocket/wsjson) subpackage |
21 |
| -- Zero alloc reads and writes |
22 |
| -- Concurrent writes |
23 |
| -- [Close handshake](https://pkg.go.dev/nhooyr.io/websocket#Conn.Close) |
24 |
| -- [net.Conn](https://pkg.go.dev/nhooyr.io/websocket#NetConn) wrapper |
25 |
| -- [Ping pong](https://pkg.go.dev/nhooyr.io/websocket#Conn.Ping) API |
26 |
| -- [RFC 7692](https://tools.ietf.org/html/rfc7692) permessage-deflate compression |
27 |
| -- [CloseRead](https://pkg.go.dev/nhooyr.io/websocket#Conn.CloseRead) helper for write only connections |
28 |
| -- Compile to [Wasm](https://pkg.go.dev/nhooyr.io/websocket#hdr-Wasm) |
29 |
| - |
30 |
| -## Roadmap |
31 |
| - |
32 |
| -See GitHub issues for minor issues but the major future enhancements are: |
33 |
| - |
34 |
| -- [ ] Perfect examples [#217](https://github.com/nhooyr/websocket/issues/217) |
35 |
| -- [ ] wstest.Pipe for in memory testing [#340](https://github.com/nhooyr/websocket/issues/340) |
36 |
| -- [ ] Ping pong heartbeat helper [#267](https://github.com/nhooyr/websocket/issues/267) |
37 |
| -- [ ] Ping pong instrumentation callbacks [#246](https://github.com/nhooyr/websocket/issues/246) |
38 |
| -- [ ] Graceful shutdown helpers [#209](https://github.com/nhooyr/websocket/issues/209) |
39 |
| -- [ ] Assembly for WebSocket masking [#16](https://github.com/nhooyr/websocket/issues/16) |
40 |
| - - WIP at [#326](https://github.com/nhooyr/websocket/pull/326), about 3x faster |
41 |
| -- [ ] HTTP/2 [#4](https://github.com/nhooyr/websocket/issues/4) |
42 |
| -- [ ] The holy grail [#402](https://github.com/nhooyr/websocket/issues/402) |
43 |
| - |
44 |
| -## Examples |
45 |
| - |
46 |
| -For a production quality example that demonstrates the complete API, see the |
47 |
| -[echo example](./internal/examples/echo). |
48 |
| - |
49 |
| -For a full stack example, see the [chat example](./internal/examples/chat). |
50 |
| - |
51 |
| -### Server |
52 |
| - |
53 |
| -```go |
54 |
| -http.HandlerFunc(func (w http.ResponseWriter, r *http.Request) { |
55 |
| - c, err := websocket.Accept(w, r, nil) |
56 |
| - if err != nil { |
57 |
| - // ... |
58 |
| - } |
59 |
| - defer c.CloseNow() |
60 |
| - |
61 |
| - ctx, cancel := context.WithTimeout(r.Context(), time.Second*10) |
62 |
| - defer cancel() |
63 |
| - |
64 |
| - var v interface{} |
65 |
| - err = wsjson.Read(ctx, c, &v) |
66 |
| - if err != nil { |
67 |
| - // ... |
68 |
| - } |
69 |
| - |
70 |
| - log.Printf("received: %v", v) |
71 |
| - |
72 |
| - c.Close(websocket.StatusNormalClosure, "") |
73 |
| -}) |
74 |
| -``` |
75 |
| - |
76 |
| -### Client |
77 |
| - |
78 |
| -```go |
79 |
| -ctx, cancel := context.WithTimeout(context.Background(), time.Minute) |
80 |
| -defer cancel() |
81 |
| - |
82 |
| -c, _, err := websocket.Dial(ctx, "ws://localhost:8080", nil) |
83 |
| -if err != nil { |
84 |
| - // ... |
85 |
| -} |
86 |
| -defer c.CloseNow() |
87 |
| - |
88 |
| -err = wsjson.Write(ctx, c, "hi") |
89 |
| -if err != nil { |
90 |
| - // ... |
91 |
| -} |
92 |
| - |
93 |
| -c.Close(websocket.StatusNormalClosure, "") |
94 |
| -``` |
95 |
| - |
96 |
| -## Comparison |
97 |
| - |
98 |
| -### gorilla/websocket |
99 |
| - |
100 |
| -Advantages of [gorilla/websocket](https://github.com/gorilla/websocket): |
101 |
| - |
102 |
| -- Mature and widely used |
103 |
| -- [Prepared writes](https://pkg.go.dev/github.com/gorilla/websocket#PreparedMessage) |
104 |
| -- Configurable [buffer sizes](https://pkg.go.dev/github.com/gorilla/websocket#hdr-Buffers) |
105 |
| -- No extra goroutine per connection to support cancellation with context.Context. This costs nhooyr.io/websocket 2 KB of memory per connection. |
106 |
| - - Will be removed soon with [context.AfterFunc](https://github.com/golang/go/issues/57928). See [#411](https://github.com/nhooyr/websocket/issues/411) |
107 |
| - |
108 |
| -Advantages of nhooyr.io/websocket: |
109 |
| - |
110 |
| -- Minimal and idiomatic API |
111 |
| - - Compare godoc of [nhooyr.io/websocket](https://pkg.go.dev/nhooyr.io/websocket) with [gorilla/websocket](https://pkg.go.dev/github.com/gorilla/websocket) side by side. |
112 |
| -- [net.Conn](https://pkg.go.dev/nhooyr.io/websocket#NetConn) wrapper |
113 |
| -- Zero alloc reads and writes ([gorilla/websocket#535](https://github.com/gorilla/websocket/issues/535)) |
114 |
| -- Full [context.Context](https://blog.golang.org/context) support |
115 |
| -- Dial uses [net/http.Client](https://golang.org/pkg/net/http/#Client) |
116 |
| - - Will enable easy HTTP/2 support in the future |
117 |
| - - Gorilla writes directly to a net.Conn and so duplicates features of net/http.Client. |
118 |
| -- Concurrent writes |
119 |
| -- Close handshake ([gorilla/websocket#448](https://github.com/gorilla/websocket/issues/448)) |
120 |
| -- Idiomatic [ping pong](https://pkg.go.dev/nhooyr.io/websocket#Conn.Ping) API |
121 |
| - - Gorilla requires registering a pong callback before sending a Ping |
122 |
| -- Can target Wasm ([gorilla/websocket#432](https://github.com/gorilla/websocket/issues/432)) |
123 |
| -- Transparent message buffer reuse with [wsjson](https://pkg.go.dev/nhooyr.io/websocket/wsjson) subpackage |
124 |
| -- [1.75x](https://github.com/nhooyr/websocket/releases/tag/v1.7.4) faster WebSocket masking implementation in pure Go |
125 |
| - - Gorilla's implementation is slower and uses [unsafe](https://golang.org/pkg/unsafe/). |
126 |
| - Soon we'll have assembly and be 3x faster [#326](https://github.com/nhooyr/websocket/pull/326) |
127 |
| -- Full [permessage-deflate](https://tools.ietf.org/html/rfc7692) compression extension support |
128 |
| - - Gorilla only supports no context takeover mode |
129 |
| -- [CloseRead](https://pkg.go.dev/nhooyr.io/websocket#Conn.CloseRead) helper for write only connections ([gorilla/websocket#492](https://github.com/gorilla/websocket/issues/492)) |
130 |
| - |
131 |
| -#### golang.org/x/net/websocket |
132 |
| - |
133 |
| -[golang.org/x/net/websocket](https://pkg.go.dev/golang.org/x/net/websocket) is deprecated. |
134 |
| -See [golang/go/issues/18152](https://github.com/golang/go/issues/18152). |
135 |
| - |
136 |
| -The [net.Conn](https://pkg.go.dev/nhooyr.io/websocket#NetConn) can help in transitioning |
137 |
| -to nhooyr.io/websocket. |
138 |
| - |
139 |
| -#### gobwas/ws |
140 |
| - |
141 |
| -[gobwas/ws](https://github.com/gobwas/ws) has an extremely flexible API that allows it to be used |
142 |
| -in an event driven style for performance. See the author's [blog post](https://medium.freecodecamp.org/million-websockets-and-go-cc58418460bb). |
143 |
| - |
144 |
| -However it is quite bloated. See https://pkg.go.dev/github.com/gobwas/ws |
145 |
| - |
146 |
| -When writing idiomatic Go, nhooyr.io/websocket will be faster and easier to use. |
147 |
| - |
148 |
| -#### lesismal/nbio |
149 |
| - |
150 |
| -[lesismal/nbio](https://github.com/lesismal/nbio) is similar to gobwas/ws in that the API is |
151 |
| -event driven for performance reasons. |
152 |
| - |
153 |
| -However it is quite bloated. See https://pkg.go.dev/github.com/lesismal/nbio |
154 |
| - |
155 |
| -When writing idiomatic Go, nhooyr.io/websocket will be faster and easier to use. |
| 3 | +https://github.com/coder/websocket |
0 commit comments