open()

in packages/database/src/realtime/BrowserPollConnection.ts [137:241]


  open(onMessage: (msg: {}) => void, onDisconnect: (a?: boolean) => void) {
    this.curSegmentNum = 0;
    this.onDisconnect_ = onDisconnect;
    this.myPacketOrderer = new PacketReceiver(onMessage);
    this.isClosed_ = false;

    this.connectTimeoutTimer_ = setTimeout(() => {
      this.log_('Timed out trying to connect.');
      // Make sure we clear the host cache
      this.onClosed_();
      this.connectTimeoutTimer_ = null;
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
    }, Math.floor(LP_CONNECT_TIMEOUT)) as any;

    // Ensure we delay the creation of the iframe until the DOM is loaded.
    executeWhenDOMReady(() => {
      if (this.isClosed_) {
        return;
      }

      //Set up a callback that gets triggered once a connection is set up.
      this.scriptTagHolder = new FirebaseIFrameScriptHolder(
        (...args) => {
          const [command, arg1, arg2, arg3, arg4] = args;
          this.incrementIncomingBytes_(args);
          if (!this.scriptTagHolder) {
            return; // we closed the connection.
          }

          if (this.connectTimeoutTimer_) {
            clearTimeout(this.connectTimeoutTimer_);
            this.connectTimeoutTimer_ = null;
          }
          this.everConnected_ = true;
          if (command === FIREBASE_LONGPOLL_START_PARAM) {
            this.id = arg1 as string;
            this.password = arg2 as string;
          } else if (command === FIREBASE_LONGPOLL_CLOSE_COMMAND) {
            // Don't clear the host cache. We got a response from the server, so we know it's reachable
            if (arg1) {
              // We aren't expecting any more data (other than what the server's already in the process of sending us
              // through our already open polls), so don't send any more.
              this.scriptTagHolder.sendNewPolls = false;

              // arg1 in this case is the last response number sent by the server. We should try to receive
              // all of the responses up to this one before closing
              this.myPacketOrderer.closeAfter(arg1 as number, () => {
                this.onClosed_();
              });
            } else {
              this.onClosed_();
            }
          } else {
            throw new Error('Unrecognized command received: ' + command);
          }
        },
        (...args) => {
          const [pN, data] = args;
          this.incrementIncomingBytes_(args);
          this.myPacketOrderer.handleResponse(pN as number, data as unknown[]);
        },
        () => {
          this.onClosed_();
        },
        this.urlFn
      );

      //Send the initial request to connect. The serial number is simply to keep the browser from pulling previous results
      //from cache.
      const urlParams: { [k: string]: string | number } = {};
      urlParams[FIREBASE_LONGPOLL_START_PARAM] = 't';
      urlParams[FIREBASE_LONGPOLL_SERIAL_PARAM] = Math.floor(
        Math.random() * 100000000
      );
      if (this.scriptTagHolder.uniqueCallbackIdentifier) {
        urlParams[FIREBASE_LONGPOLL_CALLBACK_ID_PARAM] =
          this.scriptTagHolder.uniqueCallbackIdentifier;
      }
      urlParams[VERSION_PARAM] = PROTOCOL_VERSION;
      if (this.transportSessionId) {
        urlParams[TRANSPORT_SESSION_PARAM] = this.transportSessionId;
      }
      if (this.lastSessionId) {
        urlParams[LAST_SESSION_PARAM] = this.lastSessionId;
      }
      if (this.applicationId) {
        urlParams[APPLICATION_ID_PARAM] = this.applicationId;
      }
      if (this.appCheckToken) {
        urlParams[APP_CHECK_TOKEN_PARAM] = this.appCheckToken;
      }
      if (
        typeof location !== 'undefined' &&
        location.hostname &&
        FORGE_DOMAIN_RE.test(location.hostname)
      ) {
        urlParams[REFERER_PARAM] = FORGE_REF;
      }
      const connectURL = this.urlFn(urlParams);
      this.log_('Connecting via long-poll to ' + connectURL);
      this.scriptTagHolder.addTag(connectURL, () => {
        /* do nothing */
      });
    });
  }