在多个客户端之间并发中继数据

时间:2016-03-22 13:19:55

标签: go concurrency

我目前正致力于使用WebSockets将通过服务器从手机发送的数据传输到浏览器的应用程序。我正在编写服务器,我在手机和浏览器之间有一对一的关系,如下图所示。

communication flow between mobile phone and server

但是,我希望多个会话同时工作。

我已经读过go提供了遵循“使用goroutines和channel共享内存”原则的并发模型。我更喜欢使用提到的原则而不是使用sync.Mutex原语的锁。

然而,我无法将此信息映射到我的问题,并想问你是否可以提出解决方案。

2 个答案:

答案 0 :(得分:2)

我遇到了类似的问题,我需要多个连接,每个连接都通过多个服务器相互发送数据。

我选择了WAMP协议

WAMP is an open standard WebSocket subprotocol that provides two application messaging patterns in one unified protocol:
Remote Procedure Calls + Publish & Subscribe.

您还可以查看我的一个项目,该项目用go编写并使用手头的协议:github.com/neutrinoapp/neutrino

答案 1 :(得分:1)

在Go中使用互斥锁没有任何问题。这是使用互斥锁的解决方案。

声明端点地图。我假设字符串键足以识别端点:

type endpoint struct {
    c *websocket.Conn
    sync.Mutex  // protects write to c
}

var (
   endpoints = map[string]*endpoint
   endpointsMu sync.Mutex   // protects endpoints
)

func addEndpoint(key string, c *websocket.Connection) {
   endpointsMu.Lock()
   endpoints[key] = &endpoint{c:c}
   endpointsMu.Unlock()
}

func removeEndpoint(key string) {
    endpointsMu.Lock()
    delete(endpoints, key)
    endpointsMu.Unlock()
}

func sendToEndpoint(key string, message []byte) error {
    endpointsMu.Lock()
    e := endpoints[key]
    endpointsMu.Unlock()
    if e === nil {
        return errors.New("no endpoint")
    }
    e.Lock()
    defer e.Unlock()
    return e.c.WriteMessage(websocket.TextMessage, message)
}

当客户端连接时,使用addEndpoint将连接添加到地图。关闭连接时,使用removeEndpoint从地图中删除连接。使用sendToEndpoint将消息发送到指定的端点。

可以调整Gorilla chat example来解决这个问题。将中心映射更改为connections map[string]*connection,更新频道以发送带连接和密钥的类型,并更改广播循环以发送到单个连接。