【问题标题】:Concurrent write to websocket connection并发写入 websocket 连接
【发布时间】:2019-10-29 23:53:52
【问题描述】:

我将github.com/gorilla/websocket 用于websockets。我有这个代码

type CONN struct {
    Conn *websocket.Conn
    Username string
    hand []string
    mu *sync.Mutex
}
func (c *CONN) Send(messageType int, message []byte) error {
    c.mu.Lock()
    defer c.mu.Unlock()
    return c.Conn.WriteMessage(messageType, message)
}
//later...
connection.Send(messageType, []byte("play"))
connection.Send(messageType, []byte("[\"a\", \"b\", \"c\"]"))

最后两行给了我错误。如果您需要更多代码来解决这个问题,请告诉我。这是错误:

2019/06/15 15:19:03 http: panic serving [::1]:56788: concurrent write to websocket connection
goroutine 10 [running]:
net/http.(*conn).serve.func1(0xc000164140)
    /usr/lib64/go/1.11/src/net/http/server.go:1746 +0xd0
panic(0x6654e0, 0x7125a0)
    /usr/lib64/go/1.11/src/runtime/panic.go:513 +0x1b9
github.com/gorilla/websocket.(*messageWriter).flushFrame(0xc000043a18, 0xc000016501, 0xc00001656c, 0x0, 0x4, 0x713e00, 0xc0001141e0)
    /home/victor/programs/goprograms/src/github.com/gorilla/websocket/conn.go:597 +0x631
github.com/gorilla/websocket.(*Conn).WriteMessage(0xc0001a4160, 0x1, 0xc000016568, 0x4, 0x8, 0x4, 0xc000016568)
    /home/victor/programs/goprograms/src/github.com/gorilla/websocket/conn.go:753 +0x24b
main.(*CONN).Send(0xc00015c280, 0x1, 0xc000016568, 0x4, 0x8, 0x0, 0x0)
    /home/victor/programs/goprograms/src/v/asdf/network/main.go:32 +0x9e
main.wsHandler(0x716960, 0xc00011e380, 0xc000116400)
    /home/victor/programs/goprograms/src/v/asdf/network/main.go:68 +0x501
net/http.HandlerFunc.ServeHTTP(0x6e1ab0, 0x716960, 0xc00011e380, 0xc000116400)
    /usr/lib64/go/1.11/src/net/http/server.go:1964 +0x44
net/http.(*ServeMux).ServeHTTP(0x8dadc0, 0x716960, 0xc00011e380, 0xc000116400)
    /usr/lib64/go/1.11/src/net/http/server.go:2361 +0x127
net/http.serverHandler.ServeHTTP(0xc00008d040, 0x716960, 0xc00011e380, 0xc000116400)
    /usr/lib64/go/1.11/src/net/http/server.go:2741 +0xab
net/http.(*conn).serve(0xc000164140, 0x716b60, 0xc00005a800)
    /usr/lib64/go/1.11/src/net/http/server.go:1847 +0x646
created by net/http.(*Server).Serve
    /usr/lib64/go/1.11/src/net/http/server.go:2851 +0x2f5

Here is the full code I am using - 第 75 行是设置连接的位置。我看不出地图中的一个项目下怎么会有多个连接。

【问题讨论】:

  • 恐怕我们需要minimal reproducible example。这段代码看起来不错,但我们怎么知道您没有在另一个CONN 中使用相同的*websocket.Conn? (或者可能还有其他问题)
  • @SergioTulentsev 我在问题中添加了一些代码。不幸的是,我不能很好地挑出错误,所以我不能提供一个很好的最小例子:(
  • 对 WriteMessage 的某些调用不受互斥锁的保护。对所有写入使用发送。
  • 变量连接存在数据竞争。使用竞赛检测器运行应用程序。

标签: go websocket concurrency mutex


【解决方案1】:

您的 func wsHandler(w http.ResponseWriter, r *http.Request) 未在全局变量映射 connections 上正确同步

wsHandler 的每次调用都在一个单独的 goroutine 中进行:

来自https://golang.org/pkg/net/http/#Server.ListenAndServe

ListenAndServe 侦听 TCP 网络地址 srv.Addr,然后调用 Serve 处理传入连接上的请求。

来自https://golang.org/pkg/net/http/#Server.Serve

Serve 接受 Listener l 上的传入连接,为每个连接创建一个新的服务 goroutine。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-22
    • 1970-01-01
    • 2023-03-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多