ping.go 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. /*
  2. * Copyright (c) 2013 IBM Corp.
  3. *
  4. * All rights reserved. This program and the accompanying materials
  5. * are made available under the terms of the Eclipse Public License v1.0
  6. * which accompanies this distribution, and is available at
  7. * http://www.eclipse.org/legal/epl-v10.html
  8. *
  9. * Contributors:
  10. * Seth Hoenig
  11. * Allan Stockdill-Mander
  12. * Mike Robertson
  13. */
  14. package mqtt
  15. import (
  16. "errors"
  17. "git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git/packets"
  18. "sync"
  19. "time"
  20. )
  21. type lastcontact struct {
  22. sync.Mutex
  23. lasttime time.Time
  24. }
  25. func (l *lastcontact) update() {
  26. l.Lock()
  27. defer l.Unlock()
  28. l.lasttime = time.Now()
  29. }
  30. func (l *lastcontact) get() time.Time {
  31. l.Lock()
  32. defer l.Unlock()
  33. return l.lasttime
  34. }
  35. func keepalive(c *Client) {
  36. DEBUG.Println(PNG, "keepalive starting")
  37. c.pingOutstanding = false
  38. for {
  39. select {
  40. case <-c.stop:
  41. DEBUG.Println(PNG, "keepalive stopped")
  42. c.workers.Done()
  43. return
  44. default:
  45. last := uint(time.Since(c.lastContact.get()).Seconds())
  46. //DEBUG.Printf("%s last contact: %d (timeout: %d)", PNG, last, uint(c.options.KeepAlive.Seconds()))
  47. if last > uint(c.options.KeepAlive.Seconds()) {
  48. if !c.pingOutstanding {
  49. DEBUG.Println(PNG, "keepalive sending ping")
  50. ping := packets.NewControlPacket(packets.Pingreq).(*packets.PingreqPacket)
  51. c.pingOutstanding = true
  52. //We don't want to wait behind large messages being sent, the Write call
  53. //will block until it it able to send the packet.
  54. ping.Write(c.conn)
  55. } else {
  56. CRITICAL.Println(PNG, "pingresp not received, disconnecting")
  57. c.workers.Done()
  58. c.internalConnLost(errors.New("pingresp not received, disconnecting"))
  59. return
  60. }
  61. }
  62. time.Sleep(1 * time.Second)
  63. }
  64. }
  65. }