Gorilla/Mux & Websocket 竞争条件。这样安全吗?

Gorilla/Mux & Websocket Race Condition. Is this safe?

我正在开发 websocket,最近开始使用 race 对竞争条件进行一些测试。 go run -race serve.go

得到这个结果:

WARNING: DATA RACE
Write at 0x0000019ab4a8 by goroutine 95:
  go-api/client.ServeWs()

Previous write at 0x0000019ab4a8 by goroutine 117:
  go-api/client.ServeWs()

我正在使用 gorilla/mux 并将其中一个请求升级到 websockets。我不确定它是否是由其他原因引起的,但即使是这个非常简单的设置仍然显示出竞争条件。我的 猜测 是因为 websocket 被两个例程同时写入,但只要两个请求都升级了,这有关系吗?或者是否有可能由于竞争条件而导致连接断开?

    //serve.go
    mux.HandleFunc("/data", func(w http.ResponseWriter, r *http.Request) {
        client.ServeWs(w, r)
    })
//client.go
func ServeWs(w http.ResponseWriter, r *http.Request) {
    upgrader = websocket.Upgrader{
        ReadBufferSize:  1024,
        WriteBufferSize: 1024,
        CheckOrigin: func(r *http.Request) bool {
            return true
        },
    }

    _, err := upgrader.Upgrade(w, r, nil)
    if err != nil {
        log.Println(err)
        return
    }
}

因为升级器不依赖于请求,你可以在package-level

创建升级器
var upgrader = websocket.Upgrader{ ... fields as in ServeWs ... }

并从 ServeWs 中删除对升级程序的分配。

func ServeWs(w http.ResponseWriter, r *http.Request) {
    c, err := upgrader.Upgrade(w, r, nil)
    if err != nil {
        log.Println(err)
        return
    }
    defer c.Close()