websocket is a minimal and idiomatic WebSocket library for Go.
go get nhooyr.io/websocket
- Minimal and idiomatic API
- First class context.Context support
- Fully passes the WebSocket autobahn-testsuite
- Thorough tests with 90% coverage
- Single dependency
- JSON and protobuf helpers in the wsjson and wspb subpackages
- Zero alloc reads and writes
- Concurrent writes
- Close handshake
- net.Conn wrapper
- Ping pong API
- RFC 7692 permessage-deflate compression
- Compile to Wasm
- HTTP/2 #4
For a production quality example that demonstrates the complete API, see the echo example.
For a full stack Chat example designed for chat rooms, see the chat example. It is designed for WSS so ensure your chat server is secured.
Here is an example command to get the chat server running locally on port 8080
go run . localhost:8080
http.HandlerFunc(func (w http.ResponseWriter, r *http.Request) {
c, err := websocket.Accept(w, r, nil)
if err != nil {
// ...
}
defer c.Close(websocket.StatusInternalError, "the sky is falling")
ctx, cancel := context.WithTimeout(r.Context(), time.Second*10)
defer cancel()
var v interface{}
err = wsjson.Read(ctx, c, &v)
if err != nil {
// ...
}
log.Printf("received: %v", v)
c.Close(websocket.StatusNormalClosure, "")
})
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel()
c, _, err := websocket.Dial(ctx, "ws://localhost:8080", nil)
if err != nil {
// ...
}
defer c.Close(websocket.StatusInternalError, "the sky is falling")
err = wsjson.Write(ctx, c, "hi")
if err != nil {
// ...
}
c.Close(websocket.StatusNormalClosure, "")
Advantages of gorilla/websocket:
- Mature and widely used
- Prepared writes
- Configurable buffer sizes
Advantages of nhooyr.io/websocket:
- Minimal and idiomatic API
- Compare godoc of nhooyr.io/websocket with gorilla/websocket side by side.
- net.Conn wrapper
- Zero alloc reads and writes (gorilla/websocket#535)
- Full context.Context support
- Dial uses net/http.Client
- Will enable easy HTTP/2 support in the future
- Gorilla writes directly to a net.Conn and so duplicates features of net/http.Client.
- Concurrent writes
- Close handshake (gorilla/websocket#448)
- Idiomatic ping pong API
- Gorilla requires registering a pong callback before sending a Ping
- Can target Wasm (gorilla/websocket#432)
- Transparent message buffer reuse with wsjson and wspb subpackages
- 1.75x faster WebSocket masking implementation in pure Go
- Gorilla's implementation is slower and uses unsafe.
- Full permessage-deflate compression extension support
- Gorilla only supports no context takeover mode
- We use a vendored klauspost/compress for much lower memory usage (gorilla/websocket#203)
- CloseRead helper (gorilla/websocket#492)
- Actively maintained (gorilla/websocket#370)
golang.org/x/net/websocket is deprecated. See golang/go/issues/18152.
The net.Conn can help in transitioning to nhooyr.io/websocket.
gobwas/ws has an extremely flexible API that allows it to be used in an event driven style for performance. See the author's blog post.
However when writing idiomatic Go, nhooyr.io/websocket will be faster and easier to use.