1

注: 私は、この不自然な例を解決するよりも、一般的な Go の概念/パターンを理解することに関心があります。

Go (golang) WebSocket パッケージは、簡単なエコー サーバーの例を提供します。これは次のように要約されます。

func EchoServer(ws *websocket.Conn) { io.Copy(ws, ws); }

func main() {
 http.Handle("/echo", websocket.Handler(EchoServer));
 http.ListenAndServe(":12345", nil);
}

サーバーは同時接続を処理します。接続されているすべてのクライアントに入力をエコーすることで、基本的なチャット サーバーにアップグレードしようとしています。

EchoServer ハンドラが開いている接続のそれぞれにアクセスできるようにするにはどうすればよいでしょうか?

4

1 に答える 1

6

アイデアを提供するための、ほぼ機能的な簡単な例

var c = make(chan *websocket.Conn, 5) //5 is an arbitrary buffer size
var c2 = make(chan []byte, 5)
func EchoServer(ws *websocket.Conn) {
    buff := make([]byte, 256)
    c <- ws
    for size, e := ws.Read(buff); e == nil; size, e = ws.Read(buff) {
        c2 <- buff[0:size]
    }
    ws.Close()
}
func main() {
    go func() {
        var somekindofstorage
        for {
            select {
            case newC := <-c:
                somekindofstorage.Add(newC)
            case msg := <-c2:
                for _, v := range somekindofstorage {
                    if _, e := v.Write(msg); e != nil { //assuming the client disconnected on write errors
                        somekindofstorage.Remove(v)
                    }
                }
            }
        }
    }()
    http.Handle("/echo", websocket.Handler(EchoServer));
    http.ListenAndServe(":12345", nil);
}

これにより、2 つのチャネルでリッスンするゴルーチンが開始されます。1 つは新しい接続を追加するためのもので、もう 1 つはすべてのアクティブな接続に送信するメッセージのためのものです。somekindofstorageマップまたはベクトルである可能性があります。

編集:

または、すべての接続をグローバル マップに保存し、それぞれに から書き込むこともできますEchoServer。ただし、マップは同時にアクセスできるようには設計されていません。

于 2010-08-25T14:44:38.437 に答える