Go - goroutines之间的高性能通信?

时间:2016-12-05 19:37:38

标签: go concurrency goroutine

我正在尝试在Go中编写一个小型游戏服务器。我基本上是从WebSocket库(https://github.com/gorilla/websocket)复制了一个例子。

每秒,服务器执行函数 [PDOException] SQLSTATE[HY000] [1045] Access denied for user 'root'@'localhost' (using password: NO) ,将当前时间发送给用户。当用户不执行任何操作时,此工作正常。

当用户加入,离开或发送消息时,将通过三个通道之一(每个操作一个)发送信息并执行相应的操作,但s.tick()正在跳过或延迟。我注意到,如果用户始终执行操作,则永远不会调用s.tick()

这是输出:

s.tick()

我试图检查是什么导致了这些动作之间的延迟(这些动作都没有花费很长时间),我唯一的想法就是:

  • 我的代码很糟糕(非常可能)
  • Go的频道很慢

我在循环开始时和case子句的开头检查了时间,并且通常需要超过200ms才能从通道接收数据。话虽如此,我该如何改善此解决方案的性能?我似乎无法让服务器以每秒一个刻度的速度运行,更不用说60了。

以下代码片段:

Mon, 05 Dec 2016 20:19:11 CET
Mon, 05 Dec 2016 20:19:12 CET
Mon, 05 Dec 2016 20:19:13 CET
Mon, 05 Dec 2016 20:19:15 CET
Mon, 05 Dec 2016 20:19:16 CET
Mon, 05 Dec 2016 20:19:17 CET

-- users joining and leaving

Mon, 05 Dec 2016 20:19:25 CET
Mon, 05 Dec 2016 20:19:26 CET
Mon, 05 Dec 2016 20:19:27 CET
Mon, 05 Dec 2016 20:19:28 CET
Mon, 05 Dec 2016 20:19:29 CET

1 个答案:

答案 0 :(得分:3)

试试这个:

type GameServer struct {
    players map[*Player]bool

    register   chan *Player
    unregister chan *Player

    broadcast chan []byte

    ticker *time.Ticker //use a single "global" *time.Ticker

}

func (s *GameServer) broadcastMessage(msg []byte) {
    for player := range s.players {
        player.messages <- msg
    }
}

func (s *GameServer) tick() {
    s.broadcastMessage([]byte(time.Now().Format(time.RFC1123)))
}

// question is mostly related to this function
func (s *GameServer) run() {
    for {
        select {
        case _ = <- s.Ticker.C: //use the "global" *time.Ticker instead of creating a new one every time
            s.tick()
        case client := <-s.register:
            s.players[client] = true
        case client := <-s.unregister:
            delete(s.players, client)
        case msg := <-s.broadcast:
            s.broadcastMessage(msg)
        }
    }
}

我认为您不想创建新的时间。每次调用run时都会发出警告。以上应该可以解决你的问题。