gpt4 book ai didi

go - Golang gorilla WebSocket包如何保证并发

转载 作者:IT王子 更新时间:2023-10-29 00:44:53 25 4
gpt4 key购买 nike

我研究了gorilla/websocket包的godoc。

在Godoc中明确指出

Concurrency Connections support one concurrent reader and one concurrent writer.

Applications are responsible for ensuring that no more than one goroutine calls the write methods (NextWriter, SetWriteDeadline, WriteMessage, WriteJSON, EnableWriteCompression, SetCompressionLevel) concurrently and that no more than one goroutine calls the read methods (NextReader, SetReadDeadline, ReadMessage, ReadJSON, SetPongHandler, SetPingHandler) concurrently.

The Close and WriteControl methods can be called concurrently with all other methods.

但是,在包提供的示例之一中

func (c *Conn) readPump() {
defer func() {
hub.unregister <- c
c.ws.Close()
}()
c.ws.SetReadLimit(maxMessageSize)
c.ws.SetReadDeadline(time.Now().Add(pongWait))
c.ws.SetPongHandler(func(string) error {
c.ws.SetReadDeadline(time.Now().Add(pongWait)); return nil
})
for {
_, message, err := c.ws.ReadMessage()
if err != nil {
if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway) {
log.Printf("error: %v", err)
}
break
}
message = bytes.TrimSpace(bytes.Replace(message, newline, space, -1))
hub.broadcast <- message
}
}

来源:https://github.com/gorilla/websocket/blob/a68708917c6a4f06314ab4e52493cc61359c9d42/examples/chat/conn.go#L50

这一行

c.ws.SetPongHandler(func(string) error { 
c.ws.SetReadDeadline(time.Now().Add(pongWait)); return nil
})

还有这一行

_, message, err := c.ws.ReadMessage()

似乎没有同步,因为第一行是一个回调函数,所以它应该在包中创建的Goroutine中调用,第二行在调用serveWs的Goroutine中执行

更重要的是,我应该如何确保不超过一个 goroutine 调用 SetReadDeadlineReadMessageSetPongHandlerSetPingHandler并发?

我尝试使用互斥锁并在调用上述函数时将其锁定,然后再将其解锁,但很快我就意识到了一个问题。通常(也在示例中)在 for 循环中调用 ReadMessage。但是如果 Mutext 在 ReadMessage 之前被锁定,那么在收到下一条消息之前,没有其他读取函数可以获取锁并执行

有没有更好的方法来处理这个并发问题?提前致谢。

最佳答案

确保没有并发调用读取方法的最佳方法是从单个 goroutine 执行所有读取方法。

所有 Gorilla websocket 示例都使用这种方法,包括粘贴在问题中的示例。在示例中,对读取方法的所有调用均来自 readPump 方法。 readPump 方法为单个 goroutine 上的连接调用一次。由此可见,连接读取方法不是并发调用的。

section of the documentation on control messages表示应用程序必须读取连接以处理控制消息。基于这个和 Gorilla 自己的示例,我认为可以安全地假设 ping、pong 和 close 处理程序将从应用程序的读取 goroutine 中调用,就像在当前实现中一样。如果文档可以更明确地说明这一点,那就太好了。也许提出问题?

关于go - Golang gorilla WebSocket包如何保证并发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43225340/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com