Websocket send all clients a message in Echo Framework

huangapple go评论84阅读模式
英文:

Websocket send all clients a message in Echo Framework

问题

我相信这个问题几乎与这个问题相同。

但是我在Echo框架中使用的是websocket,而不是Gorilla。所以我认为方法会有所不同。

Echo确实提供了示例。但它只展示了如何与单个客户端建立连接。当有多个客户端时,其他客户端无法从服务器接收消息。

我该如何使服务器向所有连接的客户端广播消息?

参考链接中的被接受的答案说我必须使用连接池来向所有连接广播消息。在Echo框架中我该如何做到这一点?

英文:

I believe that this question is almost the same with this.

But I use websocket in Echo framework instead of Gorilla. So I think the approach will be different.

Echo does provide the example. But it only shows how to connect with single client. When there are more than one client, the other clients don't receive message from server.

How do I make the server broadcasts message to all connected clients?

The accepted answer from referred link says that I have to use connection pool to broadcast messages to all connections. How can I do this in Echo framework?

答案1

得分: 5

你确实需要遵循连接池的相同原则。

这是一个示例,使用了一个非常基本的连接池实现:

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
}

希望对你有帮助!

英文:

You indeed need to follow the same principle of connection pool.

Here is the Echo example, with a very basic implementation of a pool:

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
}

huangapple
  • 本文由 发表于 2015年10月16日 12:41:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/33162687.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定