Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to keep connection alive in GO's websocket

Tags:

websocket

go

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?

like image 499
Jerry YY Rain Avatar asked May 14 '14 06:05

Jerry YY Rain


People also ask

Does WebSocket keep connection alive?

WebSocket uses HTTP as the initial transport mechanism, but keeps the TCP connection alive after the HTTP response is received so that it can be used for sending messages between client and server.

Do WebSockets keep a connection open?

WebSockets keeps a unique connection open while eliminating the latency problems that arise with long polling. Full-duplex asynchronous messaging is supported so that both the client and the server can stream messages to each other independently.

How long do WebSocket connections last?

A WebSocket connection can in theory last forever. Assuming the endpoints remain up, one common reason why long-lived TCP connections eventually terminate is inactivity.

Does a WebSocket timeout?

A WebSocket times out if no read or write activity occurs and no Ping messages are received within the configured timeout period. The container enforces a 30-second timeout period as the default. If the timeout period is set to -1 , no timeout period is set for the connection.


2 Answers

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
        }
    }
  }()
}
like image 171
Artem Co Avatar answered Sep 28 '22 10:09

Artem Co


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.
like image 22
laslowh Avatar answered Sep 28 '22 09:09

laslowh