Как получить доступ к другим клиентским соединениям из обработчика Go WebSocket?

Примечание. Меня больше интересует понимание общих концепций/паттернов 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 доступ к каждому открытому соединению?


person Paul Annesley    schedule 25.08.2010    source источник


Ответы (1)


Быстрый небольшой почти функциональный пример, чтобы дать вам представление

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);
}

Это запускает горутину, которая прослушивает два канала: один для добавления новых подключений и один для сообщений, отправляемых всем активным подключениям. somekindofstorage может быть картой или вектором.

Редактировать:

В качестве альтернативы вы можете просто хранить все соединения в глобальной карте и записывать в каждое из EchoServer. Но карты не предназначены для одновременного доступа.

person cthom06    schedule 25.08.2010
comment
Хорошо, спасибо. Я бы проголосовал за ваш ответ, если бы мне было позволено. Дома посмотрю подробнее. Ваше здоровье! - person Paul Annesley; 26.08.2010