Commit b201c3d9 authored by Juliusz Chroboczek's avatar Juliusz Chroboczek

Implement ping/pong exchanges and client timeouts.

parent 0dfa71ed
...@@ -707,8 +707,12 @@ func clientLoop(c *client, conn *websocket.Conn) error { ...@@ -707,8 +707,12 @@ func clientLoop(c *client, conn *websocket.Conn) error {
} }
} }
readTime := time.Now()
ticker := time.NewTicker(2 * time.Second) ticker := time.NewTicker(2 * time.Second)
defer ticker.Stop() defer ticker.Stop()
slowTicker := time.NewTicker(10 * time.Second)
defer slowTicker.Stop()
for { for {
select { select {
...@@ -718,6 +722,7 @@ func clientLoop(c *client, conn *websocket.Conn) error { ...@@ -718,6 +722,7 @@ func clientLoop(c *client, conn *websocket.Conn) error {
} }
switch m := m.(type) { switch m := m.(type) {
case clientMessage: case clientMessage:
readTime = time.Now()
err := handleClientMessage(c, m) err := handleClientMessage(c, m)
if err != nil { if err != nil {
return err return err
...@@ -793,6 +798,18 @@ func clientLoop(c *client, conn *websocket.Conn) error { ...@@ -793,6 +798,18 @@ func clientLoop(c *client, conn *websocket.Conn) error {
} }
case <-ticker.C: case <-ticker.C:
sendRateUpdate(c) sendRateUpdate(c)
case <-slowTicker.C:
if time.Since(readTime) > 90*time.Second {
return errors.New("client is dead")
}
if time.Since(readTime) > 60*time.Second {
err := c.write(clientMessage{
Type: "ping",
})
if err != nil {
return err
}
}
} }
} }
} }
...@@ -856,6 +873,12 @@ func handleClientMessage(c *client, m clientMessage) error { ...@@ -856,6 +873,12 @@ func handleClientMessage(c *client, m clientMessage) error {
if err != nil { if err != nil {
return c.error(err) return c.error(err)
} }
case "pong":
// nothing
case "ping":
c.write(clientMessage{
Type: "pong",
})
default: default:
log.Printf("unexpected message: %v", m.Type) log.Printf("unexpected message: %v", m.Type)
return protocolError("unexpected message") return protocolError("unexpected message")
......
...@@ -338,6 +338,14 @@ function serverConnect() { ...@@ -338,6 +338,14 @@ function serverConnect() {
case 'chat': case 'chat':
addToChatbox(m.id, m.username, m.value, m.me); addToChatbox(m.id, m.username, m.value, m.me);
break; break;
case 'ping':
send({
type: 'pong',
});
break;
case 'pong':
/* nothing */
break;
case 'error': case 'error':
displayError(m.value); displayError(m.value);
break; break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment