websocket 发送/接收线程安全(去例程安全)



在 GO 中编写 websocket 服务器时(在我的情况下使用 JSON 编解码器),使用两个不同的 Go 例程来处理同一连接上数据的发送和接收是否安全?

由于websocket.JSON.Receive暂停并等待接收数据,我认为一个单独的 Go 例程来处理数据发送将是一个可行的解决方案,除非在同一连接上无法并发发送/接收。

那么,下面的工作示例是不良做法吗?

package main
import (
    "fmt"
    "net/http"
    "code.google.com/p/go.net/websocket"
)
const queueSize = 20
type Input struct {
    Cmd    string
}
type Output struct {
    Cmd    string
}
func Handler(ws *websocket.Conn) {
    msgWrite := make(chan *Output, queueSize)
    var in Input
    go writeHandler(ws, msgWrite)
    for {
        err := websocket.JSON.Receive(ws, &in)
        if err != nil {
            fmt.Println(err)
            break
        } else {
            msgWrite <- &Output{Cmd: "Thanks for your message: " + in.Cmd}
        }
    }
}
func writeHandler(ws *websocket.Conn, out chan *Output) {
    var d *Output
    for {
        select {
        case d = <-out:
            if err := websocket.JSON.Send(ws, &d); err != nil {
                fmt.Println(err.Error())
            } else {
                fmt.Println("> ", d.Cmd)
            }
        }
    }
}
func main() {
    http.Handle("/echo", websocket.Handler(Handler));
    err := http.ListenAndServe(":1235", nil);
    if err != nil {
        panic("ListenAndServe: " + err.Error())
    }
    fmt.Println("Server running")
}

是的,您可以在 websocket 连接上同时调用发送、接收和关闭,就像使用所有网络一样。康恩在围棋。官方文档的简短摘录:

多个 goroutines 可以同时调用 Conn 上的方法。

此外,websocket 包还引入了一些编解码器,用于发送/写入可能以原子方式占用多个帧的消息或 JSON 数据。如果查看源,可以看到编解码器类型的发送和接收方法将持有读取或写入锁定。

自 http://www.gorillatoolkit.org/pkg/websocket

并发

连接支持一个并发

读取器和一个并发写入器。

应用程序负责确保不超过一个goroutine同时调用写入方法(NextWriter,SetWriteDeadline,WriteMessage,WriteJSON,EnableWriteCompression,SetCompressionLevel),并且不超过一个goroutine同时调用读取方法(NextReader,SetReadDeadline,ReadMessage,ReadJSON,SetPongHandler,SetPingHandler)。

Close 和 WriteControl 方法可以与所有其他方法同时调用。

相关内容

  • 没有找到相关文章

最新更新