...
1# websocket
2
3[](https://pkg.go.dev/nhooyr.io/websocket)
4[](https://nhooyr.io/websocket/coverage.html)
5
6websocket is a minimal and idiomatic WebSocket library for Go.
7
8## Install
9
10```sh
11go 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
32See 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
46For a production quality example that demonstrates the complete API, see the
47[echo example](./internal/examples/echo).
48
49For a full stack example, see the [chat example](./internal/examples/chat).
50
51### Server
52
53```go
54http.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
79ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
80defer cancel()
81
82c, _, err := websocket.Dial(ctx, "ws://localhost:8080", nil)
83if err != nil {
84 // ...
85}
86defer c.CloseNow()
87
88err = wsjson.Write(ctx, c, "hi")
89if err != nil {
90 // ...
91}
92
93c.Close(websocket.StatusNormalClosure, "")
94```
95
96## Comparison
97
98### gorilla/websocket
99
100Advantages 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
106Advantages of nhooyr.io/websocket:
107
108- Minimal and idiomatic API
109 - 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.
110- [net.Conn](https://pkg.go.dev/nhooyr.io/websocket#NetConn) wrapper
111- Zero alloc reads and writes ([gorilla/websocket#535](https://github.com/gorilla/websocket/issues/535))
112- Full [context.Context](https://blog.golang.org/context) support
113- Dial uses [net/http.Client](https://golang.org/pkg/net/http/#Client)
114 - Will enable easy HTTP/2 support in the future
115 - Gorilla writes directly to a net.Conn and so duplicates features of net/http.Client.
116- Concurrent writes
117- Close handshake ([gorilla/websocket#448](https://github.com/gorilla/websocket/issues/448))
118- Idiomatic [ping pong](https://pkg.go.dev/nhooyr.io/websocket#Conn.Ping) API
119 - Gorilla requires registering a pong callback before sending a Ping
120- Can target Wasm ([gorilla/websocket#432](https://github.com/gorilla/websocket/issues/432))
121- Transparent message buffer reuse with [wsjson](https://pkg.go.dev/nhooyr.io/websocket/wsjson) subpackage
122- [1.75x](https://github.com/nhooyr/websocket/releases/tag/v1.7.4) faster WebSocket masking implementation in pure Go
123 - Gorilla's implementation is slower and uses [unsafe](https://golang.org/pkg/unsafe/).
124 Soon we'll have assembly and be 3x faster [#326](https://github.com/nhooyr/websocket/pull/326)
125- Full [permessage-deflate](https://tools.ietf.org/html/rfc7692) compression extension support
126 - Gorilla only supports no context takeover mode
127- [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))
128
129#### golang.org/x/net/websocket
130
131[golang.org/x/net/websocket](https://pkg.go.dev/golang.org/x/net/websocket) is deprecated.
132See [golang/go/issues/18152](https://github.com/golang/go/issues/18152).
133
134The [net.Conn](https://pkg.go.dev/nhooyr.io/websocket#NetConn) can help in transitioning
135to nhooyr.io/websocket.
136
137#### gobwas/ws
138
139[gobwas/ws](https://github.com/gobwas/ws) has an extremely flexible API that allows it to be used
140in an event driven style for performance. See the author's [blog post](https://medium.freecodecamp.org/million-websockets-and-go-cc58418460bb).
141
142However it is quite bloated. See https://pkg.go.dev/github.com/gobwas/ws
143
144When writing idiomatic Go, nhooyr.io/websocket will be faster and easier to use.
145
146#### lesismal/nbio
147
148[lesismal/nbio](https://github.com/lesismal/nbio) is similar to gobwas/ws in that the API is
149event driven for performance reasons.
150
151However it is quite bloated. See https://pkg.go.dev/github.com/lesismal/nbio
152
153When writing idiomatic Go, nhooyr.io/websocket will be faster and easier to use.
View as plain text