connect method

  1. @override
void connect(
  1. EventFluxConnectionType type,
  2. String url, {
  3. Map<String, String> header = const {'Accept' : 'text/event-stream'},
  4. dynamic onConnectionClose()?,
  5. bool autoReconnect = false,
  6. ReconnectConfig? reconnectConfig,
  7. required dynamic onSuccessCallback(
    1. EventFluxResponse?
    ),
  8. dynamic onError(
    1. EventFluxException
    )?,
  9. HttpClientAdapter? httpClient,
  10. Map<String, dynamic>? body,
  11. String? tag,
  12. bool logReceivedData = false,
  13. List<MultipartFile>? files,
  14. bool multipartRequest = false,
})
override

Establishes a connection to a server-sent event (SSE) stream.

This method sets up a connection to an SSE stream based on the provided URL and connection type. It handles the data stream, manages errors, and implements an auto-reconnection mechanism.

Parameters:

  • type: The type of HTTP connection to be used (GET or POST).
  • url: The URL of the SSE stream to connect to.
  • header: HTTP headers for the request. Defaults to accepting 'text/event-stream'.
  • onConnectionClose: Callback function that is called when the connection is closed.
  • autoReconnect: Boolean value that determines if the connection should be automatically reestablished when interrupted. Defaults to false.
  • reconnectConfig: Optional configuration for reconnection attempts. Required if autoReconnect is enabled.
  • onSuccessCallback: Required callback function that is called upon a successful connection. It provides an EventFluxResponse object containing the connection status and data stream.
  • onError: Callback function for handling errors that occur during the connection or data streaming process. It receives an EventFluxException object.
  • body: Optional body for POST request types.
  • tag: Optional tag to identify the connection.
  • logReceivedData: Boolean value that determines if received data should be logged. Defaults to false.
  • files: Optional list of files to be sent with the request.
  • multipartRequest: Boolean value that determines if the request is a multipart request. Defaults to false.
  • httpClient: Optional HTTP client adapter to be used for the connection.

The method initializes an HTTP client and a StreamController for managing the SSE data. It creates an HTTP request based on the specified type, url, header, and body. Upon receiving the response, it checks the status code for success (200) and proceeds to listen to the stream. It parses each line of the incoming data to construct EventFluxData objects which are then added to the stream controller.

The method includes error handling within the stream's onError callback, which involves invoking the provided onError function, adding the error to the stream controller, and potentially triggering a reconnection attempt if autoReconnect is true.

In the case of stream closure (onDone), it disconnects the client, triggers the onConnectionClose callback, and, if autoReconnect is enabled, schedules a reconnection attempt after a delay.

Usage Example:

EventFlux eventFlux = EventFlux.instance;
eventFlux.connect(
  EventFluxConnectionType.get,
  'https://example.com/events',
  onSuccessCallback: (response) {
    response.stream?.listen((data) {
      // Handle incoming data
    });
  },
  onError: (exception) {
    // Handle error
  },
  autoReconnect: true
  reconnectConfig: ReconnectConfig(
  mode: ReconnectMode.linear || ReconnectMode.exponential,
  interval: const Duration(seconds: 2),
  maxAttempts: 5,
  reconnectCallback: () {},
),
);

This method is crucial for establishing and maintaining a stable connection to an SSE stream, handling data and errors efficiently, and providing a resilient connection experience with its auto-reconnect capability.

Implementation

@override
void connect(
  EventFluxConnectionType type,
  String url, {
  Map<String, String> header = const {'Accept': 'text/event-stream'},
  Function()? onConnectionClose,
  bool autoReconnect = false,
  ReconnectConfig? reconnectConfig,
  required Function(EventFluxResponse?) onSuccessCallback,
  Function(EventFluxException)? onError,
  HttpClientAdapter? httpClient,
  Map<String, dynamic>? body,
  String? tag,
  bool logReceivedData = false,
  List<MultipartFile>? files,
  bool multipartRequest = false,
}) {
  // This check prevents redundant connection requests when a connection is already in progress.
  // This does not prevent reconnection attempts if autoReconnect is enabled.

  // When using `spawn`, the `_status` is `disconnected` by default. so this check will always be false.
  if (_status == EventFluxStatus.connected ||
      _status == EventFluxStatus.connectionInitiated) {
    eventFluxLog('Already Connection in Progress, Skipping redundant request',
        LogEvent.info, _tag);
    return;
  }
  _status = EventFluxStatus.connectionInitiated;

  /// Set the tag for logging purposes.
  _tag = tag;

  /// If autoReconnect is enabled and reconnectConfig is not provided, log an error and return.
  if (autoReconnect && reconnectConfig == null) {
    eventFluxLog(
      "ReconnectConfig is required when autoReconnect is enabled",
      LogEvent.error,
      tag,
    );
    return;
  }

  eventFluxLog("$_status", LogEvent.info, _tag);

  /// If autoReconnect is enabled, set the maximum attempts and interval based on the reconnect configuration.
  if (reconnectConfig != null) {
    _reconnectConfig = reconnectConfig;
    _maxAttempts = reconnectConfig.maxAttempts;
    _interval = reconnectConfig.interval.inSeconds;
  }

  _isExplicitDisconnect = false;

  _start(
    type,
    url,
    header: header,
    autoReconnect: autoReconnect,
    onSuccessCallback: onSuccessCallback,
    onError: onError,
    onConnectionClose: onConnectionClose,
    body: body,
    httpClient: httpClient,
    logReceivedData: logReceivedData,
    files: files,
    multipartRequest: multipartRequest,
  );
}