我研究了大猩猩/网络套接字软件包的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.

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

这条线

这条线

似乎未同步,因为第一行是回调函数,因此应在程序包中创建的Goroutine中调用它,而第二行在调用serveWs的Goroutine中执行

更重要的是,如何确保不超过一个goroutine同时调用SetReadDeadlineReadMessageSetPongHandlerSetPingHandler

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

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

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

所有的Gorilla Websocket示例都使用这种方法,包括问题中粘贴的示例。 在该示例中,对read方法的所有调用均来自readPump方法。 对于单个goroutine上的连接,调用readPump方法一次。 因此,不会同时调用连接读取方法。

文档中有关控制消息的部分说,应用程序必须阅读连接才能处理控制消息。 基于此以及Gorilla自己的示例,我认为可以安全地假定将像当前实现中那样从应用程序的读取goroutine中调用ping,pong和close处理程序。 如果文档可以对此进行更明确的描述,那将是很好的。 也许提出问题?