class_docstr: A basic heart object for responding to a HeartMonitor.
  This is a simple wrapper with defaults for the most common
  Device model for responding to heartbeats.
  
  Builds a threadsafe zmq.FORWARDER Device, defaulting to using
  SUB/DEALER for in/out.
  
  You can specify the DEALER's IDENTITY via the optional heart_id argument.
class_docstr_tok: ["A","basic","heart","object","for","responding","to","a","HeartMonitor",".","This","is","a","simple","wrapper","with","defaults","for","the","most","common","Device","model","for","responding","to","heartbeats",".","Builds","a","threadsafe","zmq.FORWARDER","Device",",","defaulting","to","using","SUB\/DEALER","for","in\/out",".","You","can","specify","the","DEALER","'s","IDENTITY","via","the","optional","heart_id","argument","."]
code: def __init__(
      self,
      in_addr,
      out_addr,
      mon_addr=None,
      in_type=zmq.SUB,
      out_type=zmq.DEALER,
      mon_type=zmq.PUB,
      heart_id=None,
      curve_serverkey=None,
      curve_secretkey=None,
      curve_publickey=None,
  ):
      if mon_addr is None:
          self.device = ThreadDevice(zmq.FORWARDER, in_type, out_type)
      else:
          self.device = ThreadMonitoredQueue(
              in_type, out_type, mon_type, in_prefix=b"", out_prefix=b""
          )
      # do not allow the device to share global Context.instance,
      # which is the default behavior in pyzmq > 2.1.10
      self.device.context_factory = zmq.Context
  
      self.device.daemon = True
      self.device.connect_in(in_addr)
      self.device.connect_out(out_addr)
      if curve_serverkey:
          self.device.setsockopt_in(
              zmq.CURVE_SERVERKEY, curve_serverkey
          )
          self.device.setsockopt_in(
              zmq.CURVE_PUBLICKEY, curve_publickey
          )
          self.device.setsockopt_in(
              zmq.CURVE_SECRETKEY, curve_secretkey
          )
  
          self.device.setsockopt_out(
              zmq.CURVE_SERVERKEY, curve_serverkey
          )
          self.device.setsockopt_out(
              zmq.CURVE_PUBLICKEY, curve_publickey
          )
          self.device.setsockopt_out(
              zmq.CURVE_SECRETKEY, curve_secretkey
          )
          if mon_addr is not None:
              self.device.setsockopt_mon(
                  zmq.CURVE_SERVERKEY, curve_publickey
              )
              self.device.setsockopt_mon(
                  zmq.CURVE_PUBLICKEY, curve_publickey
              )
              self.device.setsockopt_mon(
                  zmq.CURVE_SECRETKEY, curve_secretkey
              )
  
      if mon_addr is not None:
          self.device.connect_mon(mon_addr)
      if in_type == zmq.SUB:
          self.device.setsockopt_in(zmq.SUBSCRIBE, b"")
      if heart_id is None:
          heart_id = uuid.uuid4().bytes
      self.device.setsockopt_out(zmq.IDENTITY, heart_id)
      self.id = heart_id
  
imports: import asyncio
  import logging
  import time
  import uuid
  import zmq
  from jupyter_client.session import Session
  from tornado import ioloop
  from traitlets import Bool, Dict, Float, Instance, Integer, Set, default
  from traitlets.config.configurable import LoggingConfigurable
  from zmq.devices import ThreadDevice, ThreadMonitoredQueue
  from zmq.eventloop.zmqstream import ZMQStream
  from ipyparallel.util import bind, connect, log_errors, set_hwm
label_desc: Use image node_id 1 to create a new Heart object  with example: obj = Heart(in_addr, out_addr, mon_addr, in_type, out_type, mon_type, heart_id, curve_serverkey, curve_secretkey, curve_publickey)