如何在Go的websocket中保持连接活跃

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

How to keep connection alive in GO's websocket

问题

我在服务器端使用了code.google.com/p/go.net/websocket,这样客户端就可以从服务器端接收通知。

然而,似乎在客户端连接到服务器后,如果客户端和服务器之间没有任何数据传输,服务器将在websocket.JSON.Receive()处返回EOF错误,这看起来像是一个超时机制。

我在谷歌上搜索了一下,似乎websocket协议有一个ping-pong心跳机制来维持连接,我想问一下code.google.com/p/go.net/websocket是否支持这个ping协议?如果我想保持客户端和服务器之间的连接活跃,我应该怎么做?

英文:

I use code.google.com/p/go.net/websocket in server, so client can get notification from server.

however, It seems after client connected to server, if there is no any data tranfer between client and server, server will return EOF error at websocket.JSON.Receive(), it looks like a timeout mechanism.

And I have search in Google, it seems websocket protocol has a ping-pong heartbeat to maintain the connection, I want to ask whether code.google.com/p/go.net/websocket support this ping protocol or not?
What should I do if I want keep connection between client and server alive?

答案1

得分: 12

这是一个适用于gorilla/websocket包的可用解决方案。

func keepAlive(c *websocket.Conn, timeout time.Duration) {
    lastResponse := time.Now()
    c.SetPongHandler(func(msg string) error {
        lastResponse = time.Now()
        return nil
    })

    go func() {
        for {
            err := c.WriteMessage(websocket.PingMessage, []byte("keepalive"))
            if err != nil {
                return
            }
            time.Sleep(timeout/2)
            if time.Since(lastResponse) > timeout {
                c.Close()
                return
            }
        }
    }()
}

这段代码实现了一个保持 WebSocket 连接活跃的功能。它会定期发送 Ping 消息给服务器,并在超时时间内检查最后一次响应的时间。如果超过超时时间没有收到 Pong 响应,就会关闭连接。

英文:

Here's working drop-in solution for gorilla/websocket package.

func keepAlive(c *websocket.Conn, timeout time.Duration) {
    lastResponse := time.Now()
    c.SetPongHandler(func(msg string) error {
       lastResponse = time.Now()
       return nil
   })

   go func() {
     for {
        err := c.WriteMessage(websocket.PingMessage, []byte("keepalive"))
        if err != nil {
            return 
        }   
        time.Sleep(timeout/2)
        if(time.Since(lastResponse) > timeout) {
            c.Close()
            return
        }
    }
  }()
}

答案2

得分: 3

截至2013年,go.net websocket库不支持(自动)保持活动消息。你有两个选择:

  • 通过定期让你的应用程序向管道发送一条被对方忽略的消息来实现“应用程序级”保持活动。
  • 切换到支持保持活动的不同websocket库(例如这个库)。**编辑:**看起来该库已被Gorilla websockets取代。
英文:

As recently as 2013, the go.net websocket library does not support (automatic) keep-alive messages. You have two options:

  • Implement an "application level" keep-alive by periodically having your application send a message down the pipe (either direction should work), that is ignored by the other side.
  • Move to a different websocket library that does support keep-alives (like this one) Edit: it looks like that library has been superseded by Gorilla websockets.

huangapple
  • 本文由 发表于 2014年5月14日 14:13:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/23646910.html
匿名

发表评论

匿名网友

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

确定