Concurrency websocket发送/接收线程安全吗?

Concurrency websocket发送/接收线程安全吗?,concurrency,websocket,go,Concurrency,Websocket,Go,在GO中编写websocket服务器时(在我的例子中使用JSON编解码器),在同一连接上使用两个不同的GO例程来处理数据的发送和接收是否安全 由于websocket.JSON.Receive暂停并等待接收数据,我认为处理数据发送的单独Go例程将是一个有效的解决方案,除非在同一连接上不可能同时发送/接收数据 那么,下面的工作示例是否为不良做法 package main import ( "fmt" "net/http" "code.google.com/p/go.net/

在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")
}
主程序包
进口(
“fmt”
“net/http”
“code.google.com/p/go.net/websocket”
)
常数queueSize=20
类型输入结构{
Cmd字符串
}
类型输出结构{
Cmd字符串
}
func处理程序(ws*websocket.Conn){
msgWrite:=make(chan*输出,队列大小)
输入变量
go writeHandler(ws,msgWrite)
为了{
err:=websocket.JSON.Receive(ws,&in)
如果错误!=零{
fmt.Println(错误)
打破
}否则{

msgWrite是的,您可以在websocket连接上同时调用Send、Receive和Close,就像您在“一切就绪”的情况下一样。官方文档的简短摘录:

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

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

引自

并发性

连接支持一个并发读卡器和一个并发写卡器

应用程序负责确保不超过一个goroutine同时调用write方法(NextWriter、SetWriteDeadline、WriteMessage、WriteJSON、EnableWriteCompression、SetCompressionLevel),并且不超过一个goroutine调用read方法(nextrader、SetReadDeadline、ReadMessage、ReadJSON、SetPongHandler、SetPingHandler)并发


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

谢谢您的解决方案!我没有在网络包中找到答案,所以我很高兴您指出了它。@tux21b您从哪里看到它将尝试组合多个帧以形成单个json消息?我在源代码和之前的注释中没有看到它或者该方法也没有指出:“//Receive从ws接收单帧,通过cd.Unmarshal解除编址,并存储在v中。”Emphasis mine。