File: ping.go

package info (click to toggle)
golang-eclipse-paho 0.9.1%2Bgit20151201-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 944 kB
  • ctags: 476
  • sloc: sh: 83; makefile: 8
file content (73 lines) | stat: -rw-r--r-- 1,759 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
/*
 * Copyright (c) 2013 IBM Corp.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Seth Hoenig
 *    Allan Stockdill-Mander
 *    Mike Robertson
 */

package mqtt

import (
	"errors"
	"git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git/packets"
	"sync"
	"time"
)

type lastcontact struct {
	sync.Mutex
	lasttime time.Time
}

func (l *lastcontact) update() {
	l.Lock()
	defer l.Unlock()
	l.lasttime = time.Now()

}

func (l *lastcontact) get() time.Time {
	l.Lock()
	defer l.Unlock()
	return l.lasttime
}

func keepalive(c *Client) {
	DEBUG.Println(PNG, "keepalive starting")
	c.pingOutstanding = false

	for {
		select {
		case <-c.stop:
			DEBUG.Println(PNG, "keepalive stopped")
			c.workers.Done()
			return
		default:
			last := uint(time.Since(c.lastContact.get()).Seconds())
			//DEBUG.Printf("%s last contact: %d (timeout: %d)", PNG, last, uint(c.options.KeepAlive.Seconds()))
			if last > uint(c.options.KeepAlive.Seconds()) {
				if !c.pingOutstanding {
					DEBUG.Println(PNG, "keepalive sending ping")
					ping := packets.NewControlPacket(packets.Pingreq).(*packets.PingreqPacket)
					c.pingOutstanding = true
					//We don't want to wait behind large messages being sent, the Write call
					//will block until it it able to send the packet.
					ping.Write(c.conn)
				} else {
					CRITICAL.Println(PNG, "pingresp not received, disconnecting")
					c.workers.Done()
					c.internalConnLost(errors.New("pingresp not received, disconnecting"))
					return
				}
			}
			time.Sleep(1 * time.Second)
		}
	}
}