我正在开发一个websocket,最近开始使用race进行一些比赛条件测试.

得到这个结果:

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并将其中一个请求升级到WebSocket.我不确定这是否是由其他原因造成的,但即使是这个非常简单的设置仍然显示出一种竞赛状态.我的guess是因为websocket被两个 routine 同时写入,但只要两个请求都得到升级,这有关系吗?或者是否有可能由于竞争条件而断开连接?

    //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
    }
}

推荐答案

因为升级程序不依赖于请求,所以可以在包级别创建升级程序

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()

Go相关问答推荐

追加一个字节数组的分配比2个字节数组的分配要少得多

如何将文件从AWS S3存储桶复制到Azure BLOB存储

通过渠道和goroutines增值1000倍

格式化 Azure SDK 的 golang 时间

如何使用 AWS sdk 在 Go 中正确解组 PartiQL 查询的结果?

在 GoLang 中对自定义 struct 体数组进行排序

Go - 永远停止带有上下文的循环

Go Build删除信息

如何从Go项目连接Microsoft Access数据库?

下载和合并时输出文件已损坏

Gorm 在自定义字符串类型上返回 scanner 错误

枚举的 Golang 验证器自定义验证规则

查找、解析和验证邮箱地址

使用 Golang 在字符串中循环重复数据

处理程序后访问 HTTP 请求上下文

使用go doc命令查看示例函数?

如何使用 Status 字段创建 Kubernetes 对象?

此代码如何生成内存对齐切片?

如何在 Windows 上使用 cgo 为 386 arch 构建 lib?

golangci-lint 的 GitHub 操作失败,无法加载 fmt