Flutter实时数据流插件lightstreamer_flutter_client的使用

Flutter实时数据流插件lightstreamer_flutter_client的使用

Lightstreamer Flutter插件使任何移动(Android或iOS)、桌面(macOS或Windows)或Web应用程序能够双向通信与Lightstreamer服务器。完全异步的API允许订阅由服务器直接发送或通过移动推送通知路由的实时数据,并向服务器发送任何消息。

该库提供了从连接故障中自动恢复的功能,自动选择最佳可用传输方式,并完全解耦订阅和连接操作。该库还提供了对移动推送通知(MPN)的支持。虽然实时订阅通过客户端连接交付更新,但MPN订阅通过推送通知交付更新,即使应用程序处于离线状态。它们由服务器的特殊模块MPN模块保持活动状态,并继续推送,无需客户端连接。然而,推送通知不是实时的,可能会被服务提供商(Google Firebase或Apple APNs)延迟,并且其传递不保证。

目录

  1. 安装
  2. 不同平台之间的差异
  3. 移动/桌面端入门
  4. Web入门
  5. 参考资料
  6. 兼容性

安装

pubspec.yaml文件的dependencies:部分中,添加以下行:

dependencies:
  lightstreamer_flutter_client: 2.1.0

Windows安装

要在Windows上使用插件,首先需要构建Lightstreamer C++ Client SDK,请参阅这些说明。请注意,下面输入的确切值取决于构建库时使用的设置。

接下来,在应用的windows文件夹中创建cmake/debug文件夹,并在其中放置一个名为LightstreamerCppClientConfig.cmake的文件,内容如下:

set(LightstreamerCppClient_ROOT_DIR "<Lightstreamer C++ Client SDK path>/bin/cpp/win/debug")
set(LightstreamerCppClient_INCLUDE_DIRS "${LightstreamerCppClient_ROOT_DIR}/include")
set(LightstreamerCppClient_LIBRARY_DIRS "${LightstreamerCppClient_ROOT_DIR}/obj/lib")
set(LightstreamerCppClient_LIBRARIES "lightstreamer_clientd")
set(LightstreamerCppClient_RUNTIME_LIBRARIES "${LightstreamerCppClient_ROOT_DIR}/lightstreamer_clientd.dll")

然后,打开windows/CMakeLists.txt文件并在顶部添加此行:set(LightstreamerCppClient_DIR "${CMAKE_CURRENT_SOURCE_DIR}/cmake/debug")

从Flutter项目的根文件夹运行命令flutter build windows来构建你的应用。

在Visual Studio中调试

可以在Microsoft Visual Studio(版本2022或更高版本)中构建、运行和调试Flutter Windows应用。

首先完成上述步骤。然后,在Visual Studio中,打开文件build/windows/x64/<your app name>.sln(确切的子文件夹位置可能取决于你的机器架构)。

可以通过右键点击<your app name>在解决方案资源管理器中,选择设为启动项目,然后按下运行按钮(▶)来运行你的应用。提醒一下,在更改代码后必须选择生成 > 生成解决方案才能再次运行。

⚠ 不同平台之间的差异 ⚠

lightstreamer_flutter_client包包含两个库:lightstreamer_client.dart用于移动和桌面平台,lightstreamer_client_web.dart用于Web平台。

这些库非常相似,因为它们暴露了相同的类和方法。这意味着使用移动/桌面库的应用几乎可以与使用Web库的应用源码兼容。但是,编写多平台应用时需要注意一些差异。

移动/桌面 vs Web

  1. 对象生命周期

    当使用移动/桌面库时,必须维护LightstreamerClientSubscriptionMpnDeviceMpnSubscription实例的引用,直到这些对象不再使用。否则可能导致这些对象(例如监听器通知)丢失的事件。

    // 正确做法
    class MyClient {
      final client = LightstreamerClient("host", "adapter");
      void connect() async {
        client.addListener(MyClientListener());
        await client.connect();
      }
    }
    
    // 错误做法
    class MyClient {
      void connect() async {
        var client = LightstreamerClient("host", "adapter");
        client.addListener(MyClientListener());
        await client.connect();
      }
    }
    

    Web库不需要此类预防措施。

  2. 异步方法

    移动/桌面库中,LightstreamerClient类的大多数方法(如connectsubscribe等)返回Future,而Web库对应的这些方法返回void或简单值。

    例如,在Web库中,建立会话如下所示:

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

    移动/桌面库的等效代码如下:

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

    虽然在此处await命令前连接是可选的,但建议包含它以捕获异常。

  3. 异常类型

    Web库抛出异常如IllegalArgumentExceptionIllegalStateException,而移动/桌面库仅抛出PlatformException

  4. 异常时机

    Web库方法在检测到无效条件时立即抛出异常,而移动/桌面库仅在某些基本方法(如connectsubscribe等)期间检查这些条件。 然而,两种库都在讨论相应方法时记录抛出的异常。

  5. iOS和macOS上的前置条件失败

    由于iOS和macOS库依赖于Swift客户端SDK,而Swift客户端SDK使用preconditions来验证方法参数,因此当Flutter应用在iOS/macOS设备上运行时,前置条件失败将导致程序执行中断。然而,在相同情况下,其他库将抛出IllegalArgumentExceptionPlatformException

推送通知

推送通知(MPN)是一种即使应用处于后台甚至未运行的情况下也能接收来自Lightstreamer服务器的消息的方法。有关更多信息,请参阅通用概念指南第5章。

推送通知在以下平台上可用:

  1. Android
  2. iOS
  3. Web(适用于Chrome、Firefox和Safari浏览器)

优化的JSON交付

Lightstreamer服务器避免使用JSON、XML或其他冗长的传输协议。相反,Lightstreamer使用基于位置的协议,最大限度地减少开销。 然而,如果某些字段的值使用JSON格式,则可以指定该字段是否适合使用JSON Patch格式作为“差异”格式进行数据交付。 有关更多信息,请参阅此页面

优化的JSON交付在所有平台(除Windows外)上都可用。

移动/桌面入门

导入库

import 'package:lightstreamer_flutter_client/lightstreamer_client.dart';

配置并开始会话

要连接到Lightstreamer服务器,需要创建一个LightstreamerClient对象,对其进行配置,并指示其连接到指定的端点。

创建一个LightstreamerClient并连接到位于https://push.lightstreamer.com的Lightstreamer服务器的最小代码如下:

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

对于每个要订阅到Lightstreamer服务器的订阅,需要一个Subscription实例。

创建一个包含三个项目和两个字段的简单订阅,这些字段在MERGE模式下订阅(参见Lightstreamer通用概念):

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

在将订阅发送到服务器之前,通常至少需要附加一个SubscriptionListener到订阅实例以消费实时更新。

以下代码显示了每次收到订阅更新时字段stock_namelast_price的值:

sub.addListener(MySubscriptionListener());

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

完整的Dart代码如下:

import 'package:lightstreamer_flutter_client/lightstreamer_client.dart';

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

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

  await Future.delayed(const Duration(seconds: 5));
}

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

发送消息

客户端还可以向服务器发送消息:

await client.sendMessage("Hello world");

以下代码展示了消息监听器的实现:

await client.sendMessage("Hello world again", "sequence1", 5000, MyMessageListener(), true);

class MyMessageListener extends ClientMessageListener {
  void onProcessed(String originalMessage, String response) {
    print("PROCESSED $originalMessage");
  }
}

完整的运行示例应用包含在项目下的example文件夹中。

日志

启用内部客户端日志记录,创建一个LoggerProvider并将其设置为LightstreamerClient的默认提供者。

var provider = ConsoleLoggerProvider(ConsoleLogLevel.DEBUG);
await LightstreamerClient.setLoggerProvider(provider);

移动推送通知(仅限Android和iOS)

该库通过Apple Push Notification Service (APNs)为Apple平台提供推送通知支持,通过Firebase Cloud Messaging (FCM)为Google平台提供推送通知支持。通过推送通知,订阅即使在应用离线时也会通过推送通知发送更新。

Firebase配置(Android)
  1. 在添加Firebase到你的Android应用之前,你需要创建一个Firebase项目来连接到你的Android应用。

  2. Firebase控制台下载google-services.json配置文件并将其移至你的应用的module (app-level)根目录。

  3. 在你的root-level (project-level) Gradle文件(<project>/build.gradle)中,作为依赖项添加Google服务插件:

    plugins {
      id 'com.android.application' version '7.3.0' apply false
      // ...
    
      // 添加Google服务Gradle插件的依赖
      id 'com.google.gms.google-services' version '4.4.2' apply false
    }
    
  4. 在你的module (app-level) Gradle文件(<project>/<app-module>/build.gradle)中,添加Google服务插件:

    plugins {
      id 'com.android.application'
    
      // 添加Google服务Gradle插件
      id 'com.google.gms.google-services'
      // ...
    }
    
  5. 在你的module (app-level) Gradle文件(<project>/<app-module>/build.gradle)中,添加Firebase消息传递的依赖项:

    dependencies {
      // ...
    
      // 导入Firebase BOM
      implementation(platform("com.google.firebase:firebase-bom:33.5.0"))
    
      // 使用BOM时,Firebase库依赖项不需要指定版本
    
      implementation 'com.google.firebase:firebase-messaging'
    }
    
  6. 确保module (app-level) Gradle文件(<project>/<app-module>/build.gradle)中的applicationId字段与google-services.json文件中的package_name字段具有相同的值。

有关更多信息,请参阅Firebase文档

APNs配置(iOS)
  1. 在你的开发者账户中,为分配给你的项目的App ID启用推送通知服务。
  2. 在xcode中,打开你的Flutter项目的xcworkspace文件。
  3. 在项目导航器中,点击Runner项目并选择Runner目标。
  4. 点击签名 & 功能并添加推送通知远程通知功能。

有关更多信息,请参阅APNs文档

订阅推送通知

在使用MPN服务之前,需要配置Lightstreamer MPN模块(仔细阅读通用概念指南中的Mobile and Web Push Notifications章节)。

然后可以创建一个MpnDevice,它代表特定应用在特定移动设备上的运行情况。

var device = MpnDevice();
await client.registerForMpn(device);

为了接收通知,需要订阅一个MpnSubscription:它包含订阅详情和监听器以监控其状态。

var items = [ "item1","item2","item3" ];
var fields = [ "stock_name","last_price","time" ];
var sub = MpnSubscription("MERGE", items, fields);
var data = {
  "stock_name": "\${stock_name}",
  "last_price": "\${last_price}",
  "time": "\${time}",
  "item": "item1" };
var format = FirebaseMpnBuilder().setData(data).build();
sub.setNotificationFormat(format);
sub.setTriggerExpression("Double.parseDouble(\$[2])&gt;45.0");
await client.subscribe(sub, true);

通知格式让你指定如何格式化通知消息。它可以包含一种特殊语法,使你能够用订阅更新的内容来组合消息(参见FirebaseMpnBuilderApnsMpnBuilder类)。

可选的触发表达式让你指定何时发送通知消息:这是一个布尔表达式,当评估为真时触发通知的发送。如果没有指定,则每次数据适配器产生更新时都会发送通知。

有关更多信息,请参阅通用概念指南中的Mobile and Web Push Notifications章节。

Web入门

导入库

  1. 获取Lightstreamer客户端Web SDK

  2. 将文件lightstreamer-core.min.js(或者如果需要Web推送通知则使用lightstreamer-mpn.min.js)复制到你的Flutter应用的web文件夹中

  3. index.html文件的<head>部分中,在其他<script>元素之前添加以下行:

    <script src="lightstreamer-core.min.js" data-lightstreamer-ns="lightstreamer"></script>
    

    (如果需要Web推送通知,则添加以下行)

    <script src="lightstreamer-mpn.min.js" data-lightstreamer-ns="lightstreamer"></script>
    
  4. 向你的应用添加以下导入:

    import 'package:lightstreamer_flutter_client/lightstreamer_client_web.dart';
    

配置并开始会话

要连接到Lightstreamer服务器,需要创建一个LightstreamerClient对象,对其进行配置,并指示其连接到指定的端点。

创建一个LightstreamerClient并连接到位于https://push.lightstreamer.com的Lightstreamer服务器的最小代码如下:

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

对于每个要订阅到Lightstreamer服务器的订阅,需要一个Subscription实例。

创建一个包含三个项目和两个字段的简单订阅,这些字段在MERGE模式下订阅(参见Lightstreamer通用概念):

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

在将订阅发送到服务器之前,通常至少需要附加一个SubscriptionListener到订阅实例以消费实时更新。

以下代码显示了每次收到订阅更新时字段stock_namelast_price的值:

sub.addListener(MySubscriptionListener());

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

完整的Dart代码如下:

import 'package:lightstreamer_flutter_client/lightstreamer_client_web.dart';

void main() async {
  var client = LightstreamerClient("https://push.lightstreamer.com/", "DEMO");
  client.connect();

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

  await Future.delayed(const Duration(seconds: 5));
}

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

发送消息

客户端还可以向服务器发送消息:

client.sendMessage("Hello world");

以下代码展示了消息监听器的实现:

client.sendMessage("Hello world again", "sequence1", 5000, MyMessageListener(), true);

class MyMessageListener extends ClientMessageListener {
  void onProcessed(String originalMessage, String response) {
    print("PROCESSED $originalMessage");
  }
}

完整的运行示例应用包含在项目下的example文件夹中。

日志

启用内部客户端日志记录,创建一个LoggerProvider并将其设置为LightstreamerClient的默认提供者。

var provider = ConsoleLoggerProvider(ConsoleLogLevel.DEBUG);
LightstreamerClient.setLoggerProvider(provider);

Web推送通知

该库通过Apple Push Notification Service (APNs)为Apple平台提供Web推送通知支持,通过Firebase Cloud Messaging (FCM)为Google平台提供Web推送通知支持。通过Web推送,订阅即使在应用离线时也会通过推送通知发送更新。

在使用MPN服务之前,需要配置Lightstreamer MPN模块(仔细阅读通用概念指南中的Mobile and Web Push Notifications章节)。

为了接收通知,需要订阅一个MpnSubscription:它包含订阅详情和监听器以监控其状态。

var items = [ "item1","item2","item3" ];
var fields = [ "stock_name","last_price","time" ];
var sub = MpnSubscription("MERGE", items, fields);
var data = {
  "stock_name": "\${stock_name}",
  "last_price": "\${last_price}",
  "time": "\${time}",
  "item": "item1" };
var format = FirebaseMpnBuilder().setData(data).build();
sub.setNotificationFormat(format);
sub.setTriggerExpression("Double.parseDouble(\$[2])&gt;45.0");
client.subscribe(sub, true);

更多关于Flutter实时数据流插件lightstreamer_flutter_client的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter实时数据流插件lightstreamer_flutter_client的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter应用中使用lightstreamer_flutter_client插件来接收实时数据流的示例代码。这个示例假定你已经有一个Lightstreamer服务器在运行,并且已经配置好了一个数据适配器来提供实时数据。

首先,确保你已经在pubspec.yaml文件中添加了lightstreamer_flutter_client依赖:

dependencies:
  flutter:
    sdk: flutter
  lightstreamer_flutter_client: ^最新版本号  # 替换为实际的最新版本号

然后,运行flutter pub get来安装依赖。

接下来,是示例代码,它展示了如何连接到Lightstreamer服务器并订阅一个数据项来接收实时数据流:

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

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

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  LightstreamerClient? _lightstreamerClient;
  Subscription? _subscription;
  String _data = '';

  @override
  void initState() {
    super.initState();
    
    // 初始化Lightstreamer客户端
    _lightstreamerClient = LightstreamerClient(
      endpoint: "ws://your-lightstreamer-server:8080/lightstreamer",  // 替换为你的Lightstreamer服务器地址
      adapterSet: "YOUR_ADAPTER_SET",  // 替换为你的适配器集名称
    );

    // 监听连接状态变化
    _lightstreamerClient?.addListener((event) {
      if (event is LightstreamerConnectionEvent) {
        print("Connection status: ${event.status}");
      }
    });

    // 连接到服务器
    _lightstreamerClient?.connect();

    // 订阅数据项
    _subscribeToData();
  }

  void _subscribeToData() {
    if (_lightstreamerClient?.isConnected!!) {
      _subscription = _lightstreamerClient?.subscribe(
        mode: "MERGE",
        items: [
          Item("YOUR_ITEM_GROUP", "YOUR_ITEM_NAME"),  // 替换为你的数据项组和名称
        ],
        fields: ["field1", "field2"],  // 替换为你想要订阅的字段
        onError: (error) {
          print("Subscription error: $error");
        },
        onMessage: (message) {
          setState(() {
            // 处理接收到的消息
            _data = message.getField("field1") ?? "";  // 示例:获取field1字段的值
          });
        },
        onClearSnapshot: () {
          print("Clear snapshot received");
        },
        onEnd: () {
          print("Subscription ended");
        },
      );
    } else {
      print("Cannot subscribe: not connected to Lightstreamer server");
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Lightstreamer Flutter Client Example'),
        ),
        body: Center(
          child: Text(
            'Received Data: $_data',
            style: TextStyle(fontSize: 24),
          ),
        ),
      ),
    );
  }

  @override
  void dispose() {
    // 断开连接并释放资源
    _subscription?.unsubscribe();
    _lightstreamerClient?.disconnect();
    super.dispose();
  }
}

在这个示例中:

  1. 我们创建了一个LightstreamerClient实例,并连接到Lightstreamer服务器。
  2. 我们使用subscribe方法订阅了一个数据项,并指定了数据项的组和名称,以及我们感兴趣的字段。
  3. 当接收到新的消息时,我们在onMessage回调中更新UI。
  4. dispose方法中,我们取消订阅并断开连接以释放资源。

请确保将YOUR_ADAPTER_SETYOUR_ITEM_GROUPYOUR_ITEM_NAME替换为你的实际配置值。此外,根据你的需求,你可能需要调整订阅的字段和其他参数。

回到顶部