constructor(
    ID_of_NodeToRenderVideo, // location on the DOM where the live feed will be rendered
    addedIceServers = [], // array of ICE servers to use in WebRTC signaling
  ) {

    this.total = {
      'downloaded': 0,
      'uploaded': 0
    }
    // initiate new torrent connection
    this.client = new WebTorrent()
    // grab DOM elements where the torrent video will be rendered to
    this.ID_of_NodeToRenderVideo = ID_of_NodeToRenderVideo;
    // store list of ICE servers
    this.addedIceServers = addedIceServers;

    this.socket = io.connect();
    // limit of child clients per client
    this.childLimit = 1;

    // indicates whether this node is the root connecting to the server
    this.isRoot = true;

    // progress trackers
    // this.$numPeers = document.querySelector('#numPeers')
    this.$downloaded = document.querySelector('#download')
    this.$uploaded = document.querySelector('#upoload')

    // create the video players on the document
    this.createVideos();

    // video tag ID from html page
    this.$play1 = document.getElementById('player1');
    this.$play2 = document.getElementById('player2');
    this.$play3 = document.getElementById('player3');
    /**
     * WebRTC Connections b/w clients
     * 
     * parent - client that's closer to server
     * child - farther away from server
     */
    this.connToParent = null;
    this.connToChild = null;

    this.torrentInfo = {
      'magnetURI1': 0,
      'magnetURI2': 0,
      'magnetURI3': 0,
      'isPlay1Playing': false,
      'isPlay1Playing': false,
      'firstIteration': 0
    }

    // displays torrent progress data
    // this.onProgress = this.onProgress.bind(this);

    this.setUpInitialConnection();

    // creates func to clear client connection when it disconnects
    this._createIceDisconnHandler = (connName) => () => {
      // have variable 
      // close client's RTC Peer Connection

      console.log('ICE disconnecting on:', connName);
      if (this[connName]) {
        this[connName].closeRTC();
        // clear connection
        this[connName] = null;

        // open socket if not already open and if from parent
        if (connName === 'connToParent') this.socket.disconnected && this.socket.open();
      }
    };

    // telling neighboring clients to reconnect
    const reconnectNeighbors = (event) => {
      // sending disconnecting message to each client
      for (let conn of ['connToParent', 'connToChild']) {
        if (this[conn]) {
          // if the connection exists, use opposite connection name
          // for example, if sending to parent on connToParent,
          // parent would be receiving message on connToChild so we'd use connToChild
          const oppConn = (conn === 'connToParent') ? 'connToChild' : 'connToParent';
          // send disconnection message telling peer on other end to disable the connection between this and them

          this[conn].sendMessage('disconnecting', {
            // will allow disconnected root to reassign root role to next client
            isRoot: this.isRoot,
            // tells neighboring clients which connection to disconnect
            disconnector: oppConn,
          });
        }
      };
    };
    // adding document unload listener : fires when this client's browser closes the page
    window.addEventListener('unload', reconnectNeighbors);
  }
Viewer class concerned with streaming video from torrents
and managing WebSocket connection to server