web_socket_client

repository·main·Indexed 41 days ago

https://github.com/felangel/web_socket_client

A simple WebSocket client for Dart featuring automatic reconnection logic with configurable backoff strategies, including ConstantBackoff, LinearBackoff, and BinaryExponentialBackoff. It provides a stream for incoming messages and a connection state monitor to track lifecycle events such as Connecting, Connected, Reconnecting, and Disconnected.

Tokens
3.9K
Snippets
18
Records
19
Agent score
52%

What's inside web_socket_client

  1. Configure reconnection backoff strategies

    main

    If a connection fails, the client automatically attempts to reconnect using a Backoff strategy. You can implement the Backoff interface for custom logic or use one of the three built-in strategies:

    1. ConstantBackoff: Waits a fixed amount of time between attempts.
    2. LinearBackoff: Increases the wait time linearly until a maximum duration is reached.
    3. BinaryExponentialBackoff: Doubles the wait time exponentially until a maximumStep is reached (Default).

    To use a specific strategy, pass it to the backoff parameter in the WebSocket constructor.

    // ConstantBackoff: Wait 1s between attempts
    const backoff = ConstantBackoff(Duration(seconds: 1));
    final socket = WebSocket(uri, backoff: backoff);
    
    // LinearBackoff: Start at 0s, increase by 1s, max 5s
    const backoff = LinearBackoff(
      initial: Duration(seconds: 0),
      increment: Duration(seconds: 1),
      maximum: Duration(seconds: 5),
    );
    final socket = WebSocket(uri, backoff: backoff);
    
    // BinaryExponentialBackoff: Start at 1s, double until step 3
    const backoff = BinaryExponentialBackoff(
      initial: Duration(seconds: 1),
      maximumStep: 3
    );
    final socket = WebSocket(uri, backoff: backoff);
  2. Send messages after connection is established

    main

    To ensure messages are not sent while the socket is still connecting, it is a best practice to wait for the Connected state using the connection stream before calling send().

    final socket = WebSocket(Uri.parse('ws://localhost:8080'));
    
    // Wait until a connection has been established.
    await socket.connection.firstWhere((state) => state is Connected);
    
    // Send a message to the server.
    socket.send('ping');
  3. Quick Start with WebSocket Client

    main

    To get started, initialize a WebSocket instance with a Uri. You can then listen to the messages stream to receive data, use send() to transmit data, and close() to terminate the connection.

    // Create a WebSocket client.
    final socket = WebSocket(Uri.parse('ws://localhost:8080'));
    
    // Listen to messages from the server.
    socket.messages.listen((message) {
      // Handle incoming messages.
    });
    
    // Send a message to the server.
    socket.send('ping');
    
    // Close the connection.
    socket.close();
  4. Handle WebSocket connection states

    main

    The ConnectionState sealed class represents the lifecycle of a WebSocket connection. You can use pattern matching (switch statements) to react to changes in the connection status.

    Available states:

    • Connecting: The connection is being established.
    • Connected: The connection is active and ready for communication.
    • Reconnecting: The connection was lost and the client is attempting to re-establish it.
    • Reconnected: The connection has been successfully re-established after a loss.
    • Disconnecting: The connection is performing a closing handshake or close() was called.
    • Disconnected: The connection is closed or failed to connect. This state provides details about why the connection ended.
    void handleState(ConnectionState state) {
      switch (state) {
        case Connecting():
          print('Connecting...');
        case Connected():
          print('Connected!');
        case Reconnecting():
          print('Connection lost. Reconnecting...');
        case Reconnected():
          print('Reconnected!');
        case Disconnecting():
          print('Disconnecting...');
        case Disconnected(code: var code, reason: var reason):
          print('Disconnected with code $code: $reason');
      }
    }
  5. Configure binaryType for Web/Protobuf usage

    main

    When using the client on the Web with Protobuf, you can set the binaryType during initialization. Note that binaryType is only applicable on the web and is ignored on desktop or mobile platforms.

    final socket = WebSocket(Uri.parse('ws://localhost:8080'), binaryType: 'arraybuffer');
  6. Receive messages from the WebSocket

    main

    Incoming messages from the server are available via the messages stream.

    final socket = WebSocket(Uri.parse('ws://localhost:8080'));
    
    // Listen for incoming messages.
    socket.messages.listen((message) {
      // Handle the incoming message.
    });
  7. Close a WebSocket connection

    main

    Calling close() initiates a closing handshake, moves the state to disconnecting, and finally to disconnected. Once disconnected, the client will not attempt to reconnect; you must create a new WebSocket instance to reconnect.

    final socket = WebSocket(Uri.parse('ws://localhost:8080'));
    
    // Later, close the connection with an optional code and reason.
    socket.close(1000, 'CLOSE_NORMAL');
  8. Monitor WebSocket connection state

    main

    You can monitor the connection status using the connection object. This object provides a state property for the current status and a stream to listen for real-time changes.

    Connection States:

    • connecting: Connection not yet established.
    • connected: Communication is possible.
    • reconnecting: Connection lost, attempting to re-establish.
    • reconnected: Connection successfully re-established.
    • disconnecting: Closing handshake in progress or close() called.
    • disconnected: Connection closed or failed to establish. (Contains nullable fields for close code, reason, error, and stack trace).
    final uri = Uri.parse('ws://localhost:8080');
    final socket = WebSocket(uri);
    
    // Listen to changes in the connection state.
    socket.connection.listen((state) {
      // Handle changes in the connection state.
    });
    
    // Query the current connection state.
    final connectionState = socket.connection.state;
  9. Establish a WebSocket connection with a timeout

    main

    The WebSocket client attempts to connect immediately upon initialization. By default, it will timeout if the connection takes longer than 60 seconds. You can provide a custom timeout duration via the constructor.

    final uri = Uri.parse('ws://localhost:8080');
    
    // Trigger a timeout if establishing a connection exceeds 10s.
    final timeout = Duration(seconds: 10);
    final socket = WebSocket(uri, timeout: timeout);
  10. Monitor connection state

    main

    The connection property returns a Connection object that tracks the current lifecycle of the WebSocket. You can observe the state of the connection (e.g., Connecting, Connected, Reconnecting, Disconnected) to react to network changes.

    webSocket.connection.stream.listen((state) {
      if (state is Connected) {
        print('Connected!');
      } else if (state is Disconnected) {
        print('Disconnected: ${state.reason}');
      }
    });
  11. Close the WebSocket connection

    main

    Use the close([int? code, String? reason]) method to terminate the connection and free resources. Providing a status code and a reason is optional. Once closed by the client, the client will not attempt to reconnect.

    // Close with a specific status code and reason
    webSocket.close(1000, 'Normal Closure');