web_socket_client icon indicating copy to clipboard operation
web_socket_client copied to clipboard

feat: If I need to disable automatic reconnection, how should I set it up?

Open xiazhichao opened this issue 7 months ago • 4 comments

Is it possible to set :

const backoff = ConstantBackoff(Duration.zero); final socket = WebSocket(uri, backoff: backoff);

Is that correct?

xiazhichao avatar May 22 '25 10:05 xiazhichao

I need to disable automatic reconnection as well. My setup may look weird, but I'm using the WebSocket to monitor and interact with a remote resource-intensive process. When the socket reconnects, the process is re-ran. That's why I need to disable reconnecting. I already tried this:

_socket = WebSocket(
  uri,
  headers: {'X-Session-Id': sessionId},
  // We don't want backoff (e.g., re-connecting)
  backoff: ConstantBackoff(Duration(days: 1)),
  binaryType: 'arraybuffer',
);

// Listen to changes in the connection state.
_socket!.connection.listen((state) {
  if (state is Disconnected || state is Reconnecting) {
    // No re-connecting
    stop();
  }
});

But that doesn't stop the reconnecting. That's because BEFORE I get the event listener to fire and to close the connection, the await _connect(); has already been reached, as the event listeners are supposedly ran after the thread unblocks or on a different thread or whatever, so I cannot disable the reconnect. The backoff strategy isn't used when reconnecting for the first time, that's the issue.

class WebSocket {
  // ...
  Future<void> _reconnect() async {
    if (_backoffDuration >= _timeout) return _closeWithTimeout();
    if (_isClosedByClient || _isConnected) return;

    _connectionController.add(const Reconnecting());

    // No backoff or nothing, no way to disable
    await _connect();

    if (_isClosedByClient || _isConnected) {
      _backoff.reset();
      _backoffTimer?.cancel();
      _backoffDuration = Duration.zero;
      return;
    }

    _backoffTimer?.cancel();
    final next = _backoff.next();
    _backoffDuration = _backoffDuration + next;
    _backoffTimer = Timer(next, _reconnect);
  }
  // ...
}

And why can't I use a different WS package - others don't support HTTP headers for connecting.

kubikaugustyn avatar Sep 10 '25 16:09 kubikaugustyn

The original web_socket_channel package does not support automatic reconnection. This package is built on top of it to provide that feature. You can still use the original package, which also supports HTTP headers.

resultanyildizi avatar Oct 03 '25 10:10 resultanyildizi

I figured out why some packages don't allow for HTTP headers for the WebSocket and realized that it's because web browsers don't allow it. So I moved to a simple package and started using query parameters for auth. But I still don't understand why would you need to reconnect a WS automatically when it's supposed to be a stateful protocol... I get reconnects for SSE, for example, but not for WS.

kubikaugustyn avatar Oct 05 '25 06:10 kubikaugustyn

I figured out why some packages don't allow for HTTP headers for the WebSocket and realized that it's because web browsers don't allow it. So I moved to a simple package and started using query parameters for auth. But I still don't understand why would you need to reconnect a WS automatically when it's supposed to be a stateful protocol... I get reconnects for SSE, for example, but not for WS.

Many messaging apps rely on web socket connection and as soon as the app is in the background mode, the OS closes the connection (especially the iOS devices). So, apps need to reconnect it when they are foreground to make the experience seamless.

resultanyildizi avatar Oct 15 '25 04:10 resultanyildizi