code: func (c *rawConnection) pingSender() error {
  	ticker := time.NewTicker(PingSendInterval / 2)
  	defer ticker.Stop()
  
  	for {
  		select {
  		case <-ticker.C:
  			d := time.Since(c.cw.Last())
  			if d < PingSendInterval/2 {
  				l.Debugln(c.id, "ping skipped after wr", d)
  				continue
  			}
  
  			l.Debugln(c.id, "ping -> after", d)
  			c.ping()
  
  		case <-c.closed:
  			return ErrClosed
  		}
  	}
  }
docs: // The pingSender makes sure that we've sent a message within the last
  // PingSendInterval. If we already have something sent in the last
  // PingSendInterval/2, we do nothing. Otherwise we send a ping message. This
  // results in an effecting ping interval of somewhere between
  // PingSendInterval/2 and PingSendInterval.