code: def heartbeat_tick(self, rate=2):
          
          if not self.heartbeat:
              return
  
          # treat actual data exchange in either direction as a heartbeat
          sent_now = self.method_writer.bytes_sent
          recv_now = self.method_reader.bytes_recv
          if self.prev_sent is None or self.prev_sent != sent_now:
              self.last_heartbeat_sent = monotonic()
          if self.prev_recv is None or self.prev_recv != recv_now:
              self.last_heartbeat_received = monotonic()
          self.prev_sent, self.prev_recv = sent_now, recv_now
  
          # send a heartbeat if it's time to do so
          if monotonic() > self.last_heartbeat_sent + self.heartbeat:
              self.send_heartbeat()
              self.last_heartbeat_sent = monotonic()
  
          # if we've missed two intervals' heartbeats, fail; this gives the
          # server enough time to send heartbeats a little late
          if (self.last_heartbeat_received and
                  self.last_heartbeat_received + 2 *
                  self.heartbeat < monotonic()):
              raise ConnectionForced('Too many heartbeats missed')
docs: Send heartbeat packets, if necessary, and fail if none have been
          received recently.  This should be called frequently, on the order of
          once per second.
  
          :keyword rate: Ignored