class_docstr: NetGear is exclusively designed to transfer video frames synchronously and asynchronously between interconnecting systems over the network in real-time.
  
  NetGear implements a high-level wrapper around PyZmQ python library that contains python bindings for ZeroMQ - a high-performance asynchronous distributed messaging library
  that provides a message queue, but unlike message-oriented middleware, its system can run without a dedicated message broker.
  
  NetGear also supports real-time Frame Compression capabilities for optimizing performance while sending the frames directly over the network, by encoding the frame before sending
  it and decoding it on the client's end automatically in real-time.
  
  !!! info
      NetGear API now internally implements robust *Lazy Pirate pattern* (auto-reconnection) for its synchronous messaging patterns _(i.e. `zmq.PAIR` & `zmq.REQ/zmq.REP`)_
      at both Server and Client ends, where its API instead of doing a blocking receive, will:
  
      * Poll the socket and receive from it only when it's sure a reply has arrived.
      * Attempt to reconnect, if no reply has arrived within a timeout period.
      * Abandon the connection if there is still no reply after several requests.
  
  NetGear as of now seamlessly supports three ZeroMQ messaging patterns:
  
  - `zmq.PAIR` _(ZMQ Pair Pattern)_
  - `zmq.REQ/zmq.REP` _(ZMQ Request/Reply Pattern)_
  - `zmq.PUB/zmq.SUB` _(ZMQ Publish/Subscribe Pattern)_
  
  _whereas the supported protocol are: `tcp` and `ipc`_.
  
  ??? tip "Modes of Operation"
  
      * **Primary Modes**
  
          NetGear API primarily has two modes of operations:
  
          * **Send Mode:** _which employs `send()` function to send video frames over the network in real-time._
  
          * **Receive Mode:** _which employs `recv()` function to receive frames, sent over the network with *Send Mode* in real-time. The mode sends back confirmation when the
          frame is received successfully in few patterns._
  
      * **Exclusive Modes**
  
          In addition to these primary modes, NetGear API offers applications-specific Exclusive Modes:
  
          * **Multi-Servers Mode:** _In this exclusive mode, NetGear API robustly **handles multiple servers at once**, thereby providing seamless access to frames and unidirectional
          data transfer from multiple Servers/Publishers across the network in real-time._
  
          * **Multi-Clients Mode:** _In this exclusive mode, NetGear API robustly **handles multiple clients at once**, thereby providing seamless access to frames and unidirectional
          data transfer to multiple Client/Consumers across the network in real-time._
  
          * **Bidirectional Mode:** _This exclusive mode **provides seamless support for bidirectional data transmission between between Server and Client along with video frames**._
  
          * **Secure Mode:** _In this exclusive mode, NetGear API **provides easy access to powerful, smart & secure ZeroMQ's Security Layers** that enables strong encryption on
          data, and unbreakable authentication between the Server and Client with the help of custom certificates/keys that brings cheap, standardized privacy and authentication
          for distributed systems over the network._
class_docstr_tok: ["NetGear","is","exclusively","designed","to","transfer","video","frames","synchronously","and","asynchronously","between","interconnecting","systems","over","the","network","in","real-time",".","NetGear","implements","a","high-level","wrapper","around","PyZmQ","python","library","that","contains","python","bindings","for","ZeroMQ","-","a","high-performance","asynchronous","distributed","messaging","library","that","provides","a","message","queue",",","but","unlike","message-oriented","middleware",",","its","system","can","run","without","a","dedicated","message","broker",".","NetGear","also","supports","real-time","Frame","Compression","capabilities","for","optimizing","performance","while","sending","the","frames","directly","over","the","network",",","by","encoding","the","frame","before","sending","it","and","decoding","it","on","the","client","'s","end","automatically","in","real-time",".","!","!","!","info","NetGear","API","now","internally","implements","robust","*","Lazy","Pirate","pattern","*","(","auto-reconnection",")","for","its","synchronous","messaging","patterns","_","(","i.e",".","`","zmq.PAIR","`","&","`","zmq.REQ\/zmq.REP","`",")","_","at","both","Server","and","Client","ends",",","where","its","API","instead","of","doing","a","blocking","receive",",","will",":","*","Poll","the","socket","and","receive","from","it","only","when","it","'s","sure","a","reply","has","arrived",".","*","Attempt","to","reconnect",",","if","no","reply","has","arrived","within","a","timeout","period",".","*","Abandon","the","connection","if","there","is","still","no","reply","after","several","requests",".","NetGear","as","of","now","seamlessly","supports","three","ZeroMQ","messaging","patterns",":","-","`","zmq.PAIR","`","_","(","ZMQ","Pair","Pattern",")","_","-","`","zmq.REQ\/zmq.REP","`","_","(","ZMQ","Request\/Reply","Pattern",")","_","-","`","zmq.PUB\/zmq.SUB","`","_","(","ZMQ","Publish\/Subscribe","Pattern",")","_","_whereas","the","supported","protocol","are",":","`","tcp","`","and","`","ipc","`","_",".","?","?","?","tip","``","Modes","of","Operation","''","*","*","*","Primary","Modes","*","*","NetGear","API","primarily","has","two","modes","of","operations",":","*","*","*","Send","Mode",":","*","*","_which","employs","`","send","(",")","`","function","to","send","video","frames","over","the","network","in","real-time._","*","*","*","Receive","Mode",":","*","*","_which","employs","`","recv","(",")","`","function","to","receive","frames",",","sent","over","the","network","with","*","Send","Mode","*","in","real-time",".","The","mode","sends","back","confirmation","when","the","frame","is","received","successfully","in","few","patterns._","*","*","*","Exclusive","Modes","*","*","In","addition","to","these","primary","modes",",","NetGear","API","offers","applications-specific","Exclusive","Modes",":","*","*","*","Multi-Servers","Mode",":","*","*","_In","this","exclusive","mode",",","NetGear","API","robustly","*","*","handles","multiple","servers","at","once","*","*",",","thereby","providing","seamless","access","to","frames","and","unidirectional","data","transfer","from","multiple","Servers\/Publishers","across","the","network","in","real-time._","*","*","*","Multi-Clients","Mode",":","*","*","_In","this","exclusive","mode",",","NetGear","API","robustly","*","*","handles","multiple","clients","at","once","*","*",",","thereby","providing","seamless","access","to","frames","and","unidirectional","data","transfer","to","multiple","Client\/Consumers","across","the","network","in","real-time._","*","*","*","Bidirectional","Mode",":","*","*","_This","exclusive","mode","*","*","provides","seamless","support","for","bidirectional","data","transmission","between","between","Server","and","Client","along","with","video","frames","*","*","._","*","*","*","Secure","Mode",":","*","*","_In","this","exclusive","mode",",","NetGear","API","*","*","provides","easy","access","to","powerful",",","smart","&","secure","ZeroMQ","'s","Security","Layers","*","*","that","enables","strong","encryption","on","data",",","and","unbreakable","authentication","between","the","Server","and","Client","with","the","help","of","custom","certificates\/keys","that","brings","cheap",",","standardized","privacy","and","authentication","for","distributed","systems","over","the","network._"]
docstr: Safely terminates the threads, and NetGear resources.
  
  Parameters:
      kill (bool): Kills ZMQ context instead of graceful exiting in receive mode.
docstr_tok: ["Safely","terminates","the","threads",",","and","NetGear","resources",".","Parameters",":","kill","(","bool",")",":","Kills","ZMQ","context","instead","of","graceful","exiting","in","receive","mode","."]
code: def close(self, kill=False):
      """
      Safely terminates the threads, and NetGear resources.
  
      Parameters:
          kill (bool): Kills ZMQ context instead of graceful exiting in receive mode.
      """
      # log it
      self.__logging and logger.debug(
          "Terminating various {} Processes.".format(
              "Receive Mode" if self.__receive_mode else "Send Mode"
          )
      )
      #  whether `receive_mode` is enabled or not
      if self.__receive_mode:
          # check whether queue mode is empty
          if not (self.__queue is None) and self.__queue:
              self.__queue.clear()
          # call immediate termination
          self.__terminate = True
          # properly close the socket
          self.__logging and logger.debug("Terminating. Please wait...")
          # wait until stream resources are released
          # (producer thread might be still grabbing frame)
          if self.__thread is not None:
              # properly handle thread exit
              if self.__thread.is_alive() and kill:
                  # force close if still alive
                  logger.warning(
                      "Thread still running...Killing it forcefully!"
                  )
                  self.__msg_context.destroy()
                  self.__thread.join()
              else:
                  self.__thread.join()
                  self.__msg_socket.close(linger=0)
              self.__thread = None
          self.__logging and logger.debug("Terminated Successfully!")
      else:
          # indicate that process should be terminated
          self.__terminate = True
          # log if kill enabled
          kill and logger.warning(
              "`kill` parmeter is only available in the receive mode."
          )
          # check if all attempts of reconnecting failed, then skip to closure
          if (self.__pattern < 2 and not self.__max_retries) or (
              self.__multiclient_mode and not self.__port_buffer
          ):
              try:
                  # properly close the socket
                  self.__msg_socket.setsockopt(zmq.LINGER, 0)
                  self.__msg_socket.close()
              except ZMQError:
                  pass
              finally:
                  # exit
                  return
  
          if self.__multiserver_mode:
              # check if multiserver_mode
              # send termination flag to client with its unique port
              term_dict = dict(terminate_flag=True, port=self.__port)
          else:
              # otherwise send termination flag to client
              term_dict = dict(terminate_flag=True)
  
          try:
              if self.__multiclient_mode:
                  for _ in self.__port_buffer:
                      self.__msg_socket.send_json(term_dict)
              else:
                  self.__msg_socket.send_json(term_dict)
  
              # check for confirmation if available within 1/5 timeout
              if self.__pattern < 2:
                  self.__logging and logger.debug(
                      "Terminating. Please wait..."
                  )
                  if self.__msg_socket.poll(
                      self.__request_timeout // 5, zmq.POLLIN
                  ):
                      self.__msg_socket.recv()
          except Exception as e:
              if not isinstance(e, ZMQError):
                  logger.exception(str(e))
          finally:
              # properly close the socket
              self.__msg_socket.setsockopt(zmq.LINGER, 0)
              self.__msg_socket.close()
              self.__logging and logger.debug(
                  "Terminated Successfully!"
              )
  
file_path: vidgear/vidgear/gears/netgear.py
imports: import os
  import time
  import string
  import secrets
  import numpy
  import logging
  from threading import Thread
  from collections import deque
  from os.path import expanduser
  from .helper import logger_handler, generate_auth_certificates, check_WriteAccess, check_open_port, import_dependency_safe, logcurr_vidgear_ver
label_desc: Use image node_id 5 for calling the NetGear obj's underlying member method code with example usage: obj.close(kill) without return types