probe method

void probe(
  1. dynamic name
)

Probes a transport.

@param {String} transport name @api private

Implementation

void probe(name) {
  _logger.fine('probing transport "$name"');
  Transport? transport = createTransport(name, {'probe': true});
  var failed = false;
  var cleanup;
  priorWebsocketSuccess = false;

  var onTransportOpen = (_) {
    if (onlyBinaryUpgrades == true) {
      var upgradeLosesBinary =
          supportsBinary == false && transport!.supportsBinary == false;
      failed = failed || upgradeLosesBinary;
    }
    if (failed) return;

    _logger.fine('probe transport "$name" opened');
    transport!.send([
      {'type': 'ping', 'data': 'probe'}
    ]);
    transport!.once('packet', (msg) {
      if (failed) return;
      if ('pong' == msg['type'] && 'probe' == msg['data']) {
        _logger.fine('probe transport "$name" pong');
        upgrading = true;
        emit('upgrading', transport);
        if (transport == null) return;
        priorWebsocketSuccess = 'websocket' == transport!.name;

        _logger.fine('pausing current transport "${transport!.name}"');
        if (this.transport is PollingTransport) {
          (this.transport as PollingTransport).pause(() {
            if (failed) return;
            if ('closed' == readyState) return;
            _logger.fine('changing transport and sending upgrade packet');

            cleanup();

            setTransport(transport);
            transport!.send([
              {'type': 'upgrade'}
            ]);
            emit('upgrade', transport);
            transport = null;
            upgrading = false;
            flush();
          });
        }
      } else {
        _logger.fine('probe transport "$name" failed');
        emit('upgradeError',
            {'error': 'probe error', 'transport': transport!.name});
      }
    });
  };

  var freezeTransport = () {
    if (failed) return;

    // Any callback called by transport should be ignored since now
    failed = true;

    cleanup();

    transport!.close();
    transport = null;
  };

  // Handle any error that happens while probing
  var onerror = (err) {
    final oldTransport = transport;
    freezeTransport();

    _logger.fine('probe transport "$name" failed because of error: $err');

    emit('upgradeError',
        {'error': 'probe error: $err', 'transport': oldTransport!.name});
  };

  var onTransportClose = (_) => onerror('transport closed');

  // When the socket is closed while we're probing
  var onclose = (_) => onerror('socket closed');

  // When the socket is upgraded while we're probing
  var onupgrade = (to) {
    if (transport != null && to.name != transport!.name) {
      _logger.fine('"${to.name}" works - aborting "${transport!.name}"');
      freezeTransport();
    }
  };

  // Remove all listeners on the transport and on self
  cleanup = () {
    transport!.off('open', onTransportOpen);
    transport!.off('error', onerror);
    transport!.off('close', onTransportClose);
    off('close', onclose);
    off('upgrading', onupgrade);
  };

  transport!.once('open', onTransportOpen);
  transport!.once('error', onerror);
  transport!.once('close', onTransportClose);

  once('close', onclose);
  once('upgrading', onupgrade);

  transport!.open();
}