8

GO で Websocket サーバーを作成する場合 (私の場合は JSON コーデックを使用)、同じ接続でデータの送受信を処理するために 2 つの異なる 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")
}
4

2 に答える 2

12

はい、Go のすべてのnet.Connでできるように、Websocket 接続で Send、Receive、および Close を同時に呼び出すことができます。公式ドキュメントからの短い抜粋:

複数のゴルーチンが Conn のメソッドを同時に呼び出すことができます。

さらに、websocket パッケージは、複数のフレームをアトミックに占有する可能性があるメッセージまたは JSON データを送信/書き込みするためのいくつかのコーデックも導入します。ソースを見ると、Codec タイプの Send and Receive メソッドが読み取りロックまたは書き込みロックを保持していることがわかります。

于 2012-06-11T19:12:35.377 に答える