Lightstreamer Flutter Plugin 2.1.0

Overview

In the past months, the Lightstreamer Flutter plugin has undergone significant development to ensure seamless integration with the Lightstreamer platform, the leading “last-mile” event broker. By aligning its API with that of other Lightstreamer client SDKs, the plugin offers a consistent and familiar development experience across different platforms. This harmonization streamlines the learning curve for developers, enabling them to leverage their existing knowledge and skills to build real-time applications with Flutter. Whether you’re building for mobile (Android or iOS), desktop (macOS or Windows) or web, the Lightstreamer Flutter plugin provides a unified approach to accessing real-time data, empowering you to create dynamic and responsive user experiences.

Architecture

The Lightstreamer Flutter plugin consists of two primary components:

1. Dart Layer This unified API layer provides a consistent interface for interacting with a Lightstreamer Server, regardless of the underlying platform. It abstracts away platform-specific complexities, making it easier for developers to work with the plugin across different environments.

2. Platform-Specific Implementation This component handles the low-level communication with the Lightstreamer Server, leveraging the native Lightstreamer Client SDK for each platform (e.g., Android, iOS, Web, Windows, macOS). By using the native SDKs, the plugin ensures optimal performance and seamless integration with the platform’s specific features.

This modular design allows the Lightstreamer Flutter plugin to support a wide range of platforms, offering a consistent developer experience while maintaining high performance and reliability.

At the core of this architecture lies Flutter Channels, a flexible message passing mechanism designed to enable bidirectional communication between Dart code and the native platform code. Using this mechanism, the Dart layer sends messages to its native host over a platform channel. The native host, in turn, listens to this channel, receives the message, and then interacts with the platform’s native APIs to perform the requested operation. Once the operation is completed, the native host sends a response back to the Dart layer through the same channel.

Usage

This guide walks you through establishing a basic connection and subscribing to real-time data updates using the Lightstreamer Flutter plugin.

1. Import the Plugin

The first step involves incorporating the Lightstreamer Flutter Client plugin into your Flutter project. Add the following line to your pubspec.yaml file:

dependencies:
  lightstreamer_flutter_client: ^latest

Run flutter pub get to download and install the plugin. Once installed, you can import it into your source code files:

import 'package:lightstreamer_flutter_client/lightstreamer_client.dart';

2. Connect to a Lightstreamer Server

To connect to a Lightstreamer Server, you’ll need to create a LightstreamerClient object. This object manages the connection and data subscription process. Here’s an example of establishing a connection to the Lightstreamer demo server:

var client = LightstreamerClient("https://push.lightstreamer.com/", "DEMO");
await client.connect();

This code snippet creates a new LightstreamerClient instance, specifying the server URL (“https://push.lightstreamer.com/”) and the adapter set (“DEMO”). The await client.connect() line initiates the connection asynchronously, waiting for it to complete before proceeding.

3. Define Your Subscription

Next, you need to define the specific data you want to receive from the server by creating a Subscription object. This object identifies the items and fields that you’re interested in subscribing to.

For example, the following code creates a subscription that includes three items (“item1”, “item2”, “item3”) and requests data updates for the fields “stock_name” and “last_price” in MERGE mode. It also sets the data adapter and requests a snapshot of the initial data:

var items  = [ "item1","item2","item3" ];
var fields = [ "stock_name","last_price" ];
var sub = Subscription("MERGE", items, fields);
sub.setDataAdapter("QUOTE_ADAPTER");
sub.setRequestedSnapshot("yes");

4. Subscribe and Listen for Updates

Once you have a configured subscription, you can subscribe to the server using the client.subscribe(sub) method.

Before subscribing, it’s recommended to attach a SubscriptionListener to the Subscription object. This listener receives notifications whenever there’s an update for the subscribed data.

The provided example demonstrates a custom MySubscriptionListener class that prints the updated values of stock_name and last_price for each update:

sub.addListener(MySubscriptionListener());

class MySubscriptionListener extends SubscriptionListener {
  void onItemUpdate(ItemUpdate update) {
    print("UPDATE ${update.getValue("stock_name")} ${update.getValue("last_price")}");
  }
}

5. Putting It All Together

Here’s a simple Flutter app that demonstrates connecting, subscribing, and receiving real-time updates:

import 'package:flutter/material.dart';
import 'package:lightstreamer_flutter_client/lightstreamer_client.dart';

void main() async {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'Flutter Demo',
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  final String title;
  const MyHomePage({super.key, required this.title});
  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  var text = '';
  var client = LightstreamerClient("https://push.lightstreamer.com/", "DEMO");
  var sub = Subscription("MERGE", [ "item1","item2","item3" ], [ "stock_name","last_price" ]);

  _MyHomePageState() {
    LightstreamerClient.setLoggerProvider(ConsoleLoggerProvider(ConsoleLogLevel.DEBUG));
    sub.setDataAdapter("QUOTE_ADAPTER");
    sub.setRequestedSnapshot("yes");
    sub.addListener(MySubscriptionListener((String s) {
      setState(() {
        text = s;
      });
    }));
    client.subscribe(sub);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ElevatedButton(
              child: const Text('Connect/Disconnect'),
              onPressed: () async {
                if (await client.getStatus() == 'DISCONNECTED') {
                  await client.connect();
                } else {
                  await client.disconnect();
                }
              }
            ),
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: Text(text),
            ),
          ],
        ),
      ),
    );
  }
}

class MySubscriptionListener extends SubscriptionListener {
  final void Function(String) cb;
  MySubscriptionListener(this.cb);

  @override
  void onItemUpdate(ItemUpdate update) {
    cb("${update.getValue("stock_name")} ${update.getValue("last_price")}");
  }
}

This code defines a subscription for stock data, and attaches a listener to receive updates. When the `Connect/Disconnect` button is pressed, the code connects to a Lightstreamer server to demonstrate receiving real-time data.

Running

The example code above can be run without any changes on Android, iOS, macOS, and Windows (*). Try it out by creating a new Flutter app, pasting the example into the lib/main.dart file, and running it with the command flutter run.

Depending on the target platform, some extra configuration steps may be necessary:

  • On macOS, you may need to set up specific entitlements.
  • On Windows, you must first build and install the Lightstreamer C++ Client library as described here.

The Lightstreamer Flutter Plugin is also available for the Web. However, there are some differences to consider between mobile/desktop targets and the web target. For further details, refer to these notes.

Conclusion

This example demonstrates the ease of creating a multi-platform real-time application that shares the bulk of the code.

To deepen your knowledge of Lightstreamer technology, check out the following resources:

December 23, 2024
Originally published: December 23, 2024


4 min read

Table of Contents