refactor: migrate WebSocket library from coder to gorilla

Replace github.com/coder/websocket with github.com/gorilla/websocket in go.mod and update SDK example code. This change improves performance and simplifies API usage by switching to the more matured gorilla library, reducing context dependencies and using standard upgrade/JSON methods.

lemon-mint committed Oct 24, 2025 at 16:30 UTC bf68a895298a31cbd608dfb42e57b6054218dfcc
3 files changed +11 -21
go.mod
+1 -2
@@ -5,8 +5,8 @@ go 1.25.3
5 require (
6 github.com/cockroachdb/crlib v0.0.0-20251001180057-2a49e1873587
7 github.com/cockroachdb/pebble v1.1.5
8 - github.com/coder/websocket v1.8.14
8 github.com/go-chi/chi/v5 v5.2.3
9 + github.com/gorilla/websocket v1.5.3
10 github.com/libp2p/go-libp2p v0.44.0
11 github.com/libp2p/go-libp2p-pubsub v0.15.0
12 github.com/multiformats/go-multiaddr v0.16.0
@@ -33,7 +33,6 @@ require (
33 github.com/gogo/protobuf v1.3.2 // indirect
34 github.com/golang/snappy v0.0.4 // indirect
35 github.com/google/uuid v1.6.0 // indirect
36 - github.com/gorilla/websocket v1.5.3 // indirect
36 github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
37 github.com/huin/goupnp v1.3.0 // indirect
38 github.com/inconshreveable/mousetrap v1.1.0 // indirect
go.sum
-2
@@ -37,8 +37,6 @@ github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwP
37 github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg=
38 github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo=
39 github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ=
40 -github.com/coder/websocket v1.8.14 h1:9L0p0iKiNOibykf283eHkKUHHrpG7f65OE3BhhO7v9g=
41 -github.com/coder/websocket v1.8.14/go.mod h1:NX3SzP+inril6yawo5CQXx8+fk145lPDC6pumgx0mVg=
40 github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
41 github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
42 github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
sdk/go/examples/chat/view.go
+10 -17
@@ -1,7 +1,6 @@
1 package main
2
3 import (
4 - "context"
4 "html/template"
5 "net/http"
6 "sort"
@@ -9,9 +8,8 @@ import (
8 "sync"
9 "time"
10
12 - "github.com/coder/websocket"
13 - "github.com/coder/websocket/wsjson"
11 "github.com/go-chi/chi/v5"
12 + "github.com/gorilla/websocket"
13 "github.com/rs/zerolog/log"
14 )
15
@@ -63,9 +61,7 @@ func (h *hub) broadcast(m message) {
61 }
62 }
63 for _, c := range conns {
66 - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
67 - _ = wsjson.Write(ctx, c, m)
68 - cancel()
64 + _ = c.WriteJSON(m)
65 }
66 }
67
@@ -112,7 +108,7 @@ func (h *hub) closeAll() {
108 }
109 h.mu.Unlock()
110 for _, c := range conns {
115 - _ = c.Close(websocket.StatusGoingAway, "server shutdown")
111 + _ = c.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseGoingAway, "server shutdown"))
112 }
113 }
114
@@ -122,22 +118,20 @@ func (h *hub) wait() {
118 }
119
120 func handleWS(w http.ResponseWriter, r *http.Request, h *hub) {
125 - conn, err := websocket.Accept(w, r, &websocket.AcceptOptions{
126 - // Allow any origin for demo simplicity. Consider tightening in production.
127 - OriginPatterns: []string{"*"},
128 - })
121 + upgrader := websocket.Upgrader{
122 + CheckOrigin: func(r *http.Request) bool { return true },
123 + }
124 + conn, err := upgrader.Upgrade(w, r, nil)
125 if err != nil {
126 return
127 }
132 - // Use a connection-scoped context not tied to the HTTP request lifecycle.
133 - connCtx, cancelConn := context.WithCancel(context.Background())
128 h.mu.Lock()
129 h.conns[conn] = struct{}{}
130 backlog := append([]message(nil), h.messages...)
131 h.mu.Unlock()
132
133 for _, m := range backlog {
140 - _ = wsjson.Write(connCtx, conn, m)
134 + _ = conn.WriteJSON(m)
135 }
136 h.wg.Add(1)
137 go func() {
@@ -169,8 +163,7 @@ func handleWS(w http.ResponseWriter, r *http.Request, h *hub) {
163 h.broadcast(message{TS: time.Now().UTC(), User: leftUser, Event: "left"})
164 h.broadcastRoster()
165 }
172 - _ = conn.Close(websocket.StatusNormalClosure, "")
173 - cancelConn()
166 + _ = conn.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
167 h.wg.Done()
168 }()
169 for {
@@ -179,7 +172,7 @@ func handleWS(w http.ResponseWriter, r *http.Request, h *hub) {
172 Text string `json:"text"`
173 UID string `json:"uid"`
174 }
182 - if err := wsjson.Read(connCtx, conn, &req); err != nil {
175 + if err := conn.ReadJSON(&req); err != nil {
176 return
177 }
178 if req.User == "" {