Websocket отправляет всем клиентам сообщение в Echo Framework

Я считаю, что этот вопрос почти такой же с этим.

Но я использую websocket в Echo Framework вместо Gorilla. Поэтому я думаю, что подход будет другим.

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

Как заставить сервер транслировать сообщения всем подключенным клиентам?

Принятый ответ по указанной ссылке говорит о том, что я должен использовать пул соединений для трансляции сообщений всем соединениям. Как я могу сделать это в Echo Framework?

1 ответ

Решение

Вы действительно должны следовать тому же принципу пула соединений.

Вот пример Echo с очень простой реализацией пула:

package main

import (
    "fmt"

    "sync"

    "github.com/labstack/echo"
    mw "github.com/labstack/echo/middleware"
    "golang.org/x/net/websocket"
)

var connectionPool = struct {
    sync.RWMutex
    connections map[*websocket.Conn]struct{}
}{
    connections: make(map[*websocket.Conn]struct{}),
}

func main() {
    e := echo.New()

    e.Use(mw.Logger())
    e.Use(mw.Recover())

    e.Static("/", "public")
    e.WebSocket("/ws", func(c *echo.Context) (err error) {
        ws := c.Socket()

        connectionPool.Lock()
        connectionPool.connections[ws] = struct{}{}

        defer func(connection *websocket.Conn){
            connectionPool.Lock()
            delete(connectionPool.connections, connection)
            connectionPool.Unlock()
        }(ws)

        connectionPool.Unlock()

        msg := ""

        for {
            if err = websocket.Message.Receive(ws, &msg); err != nil {
                return err
            }
            err = sendMessageToAllPool(msg)
            if err != nil {
                return err
            }
            fmt.Println(msg)
        }
        return err
    })

    e.Run(":1323")
}

func sendMessageToAllPool(message string) error {
    connectionPool.RLock()
    defer connectionPool.RUnlock()
    for connection := range connectionPool.connections {
        if err := websocket.Message.Send(connection, message); err != nil {
            return err
        }
    }
    return nil
}
Другие вопросы по тегам