def heartbeat_tick(self, rate=<NUM_LIT:2>):
if not self.heartbeat:<EOL><INDENT>return<EOL><DEDENT>sent_now = self.method_writer.bytes_sent<EOL>recv_now = self.method_reader.bytes_recv<EOL>if self.prev_sent is None or self.prev_sent != sent_now:<EOL><INDENT>self.last_heartbeat_sent = monotonic()<EOL><DEDENT>if self.prev_recv is None or self.prev_recv != recv_now:<EOL><INDENT>self.last_heartbeat_received = monotonic()<EOL><DEDENT>self.prev_sent, self.prev_recv = sent_now, recv_now<EOL>if monotonic() > self.last_heartbeat_sent + self.heartbeat:<EOL><INDENT>self.send_heartbeat()<EOL>self.last_heartbeat_sent = monotonic()<EOL><DEDENT>if (self.last_heartbeat_received and<EOL>self.last_heartbeat_received + <NUM_LIT:2> *<EOL>self.heartbeat < monotonic()):<EOL><INDENT>raise ConnectionForced('<STR_LIT>')<EOL><DEDENT>
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