Flutter事件发布订阅插件belatuk_pub_sub的使用

发布于 1周前 作者 vueper 来自 Flutter

Flutter事件发布订阅插件belatuk_pub_sub的使用

简介

belatuk_pub_sub 是一个用于在 Flutter 应用中实现事件发布/订阅模式的插件。它支持多个适配器(如 Isolates 和 JSON-RPC 2.0),可以在不同的环境中使用,包括服务器端和浏览器端。

特点

  • 简单易用:提供简单的 API 来发布和订阅事件。
  • 多适配器支持:支持多种通信方式,如 Isolates 和 JSON-RPC 2.0。
  • 安全性:支持客户端认证,确保只有受信任的客户端可以发布和订阅事件。

安装

在你的 pubspec.yaml 文件中添加 belatuk_pub_sub 作为依赖:

dependencies:
  belatuk_pub_sub: ^6.2.0

然后,在终端运行 dart pub get 来安装依赖。

使用

基本用法

belatuk_pub_sub 提供了一个典型的发布/订阅 API。以下是一个基本的示例,展示了如何设置一个服务器并创建客户端来订阅和发布事件。

服务器端

import 'package:belatuk_pub_sub/belatuk_pub_sub.dart' as pub_sub;

void main() async {
  // 创建一个服务器,并添加适配器
  var server = pub_sub.Server([
    pub_sub.IsolateAdapter(),
  ]);

  // 注册客户端
  server.registerClient(pub_sub.ClientInfo('client1', canPublish: true, canSubscribe: true));
  server.registerClient(pub_sub.ClientInfo('client2', canPublish: false, canSubscribe: true));

  // 启动服务器
  server.start();
}

客户端

import 'dart:isolate';
import 'package:belatuk_pub_sub/belatuk_pub_sub.dart' as pub_sub;

void isolateMain(List args) {
  // 创建一个客户端
  var client = pub_sub.IsolateClient('client${args[0]}', args[1] as SendPort);

  // 订阅事件
  client.subscribe('user::logged_in').then((sub) {
    // 监听事件
    sub.listen((msg) {
      print('Logged in: $msg');
    });
  });

  // 发布事件
  client.publish('user::logged_in', 'User1');
}

主函数

import 'dart:io';
import 'dart:isolate';
import 'package:belatuk_pub_sub/isolate.dart';
import 'package:belatuk_pub_sub/belatuk_pub_sub.dart';

void main() async {
  // 创建一个服务器
  var adapter = IsolateAdapter();
  var server = Server([adapter]);

  // 注册客户端
  for (var i = 0; i < Platform.numberOfProcessors - 1; i++) {
    server.registerClient(ClientInfo('client$i'));
  }

  // 启动服务器
  server.start();

  // 创建隔离进程
  for (var i = 0; i < Platform.numberOfProcessors - 1; i++) {
    await Isolate.spawn(isolateMain, [i, adapter.receivePort.sendPort]);
  }

  // 也可以在主进程中运行客户端
  isolateMain([0, adapter.receivePort.sendPort]);
}

详细说明

受信任的客户端

如果你的客户端来自受信任的源,你可以不显式注册客户端。例如,通过 Isolate 连接的客户端总是受信任的。

pub_sub.IsolateClient(null);

访问控制

所有未受信任的客户端必须在服务器启动前注册。你不能在服务器启动后注册新的客户端。

server.registerClient(const ClientInfo('<client-id>'));
server.registerClient(const ClientInfo('<client-id>', canPublish: false));
server.registerClient(const ClientInfo('<client-id>', canSubscribe: false));
server.registerClient(const ClientInfo('<client-id>', canPublish: false, canSubscribe: false));

Isolates

如果你的应用运行在多个隔离进程中,可以使用 package:belatuk_pub_sub/isolate.dart。你需要指定一个主隔离进程。

import 'dart:isolate';
import 'package:belatuk_pub_sub/isolate.dart' as pub_sub;

void main() async {
  var adapter = pub_sub.IsolateAdapter();
  var server = pub_sub.Server([adapter]);

  for (int i = 0; i < Platform.numberOfProcessors - 1; i++) {
    server.registerClient(pub_sub.ClientInfo('client$i'));
  }

  server.start();

  for (int i = 0; i < Platform.numberOfProcessors - 1; i++) {
    Isolate.spawn(isolateMain, [i, adapter.receivePort.sendPort]);
  }

  isolateMain([0, adapter.receivePort.sendPort]);
}

void isolateMain(List args) {
  var client = pub_sub.IsolateClient('client${args[0]}', args[1] as SendPort);

  client.subscribe('user::logged_in').then((sub) {
    sub.listen((msg) {
      print('Logged in: $msg');
    });
  });
}

JSON-RPC 2.0

如果你不在隔离进程中运行,可以使用 package:belatuk_pub_sub/json_rpc_2.dart。这个库利用 package:json_rpc_2package:stream_channel 创建客户端和服务器,可以运行在任何介质上,如 WebSockets 或 TCP Sockets。

import 'package:belatuk_pub_sub/json_rpc_2.dart' as pub_sub;

void main() async {
  var adapter = pub_sub.JsonRpc2Adapter(
    // 配置你的 StreamChannel
  );

  var server = pub_sub.Server([adapter]);

  server.registerClient(pub_sub.ClientInfo('<client-id>'));

  server.start();
}

协议

belatuk_pub_sub 基于一个简单的 RPC 协议。数据格式如下:

请求

interface Request {
  request_id: string;
  client_id: string;
  params: {
    value?: any;
    event_name?: string;
    subscription_id?: string;
  }
}

响应

interface Response {
  status: boolean;
  error_message?: string;
  request_id: string;
  result?: {
    listeners?: number;
    subscription_id?: string;
  }
}

客户端方法

  • subscribe(event_name: string): 订阅事件。
  • unsubscribe(subscription_id: string): 取消订阅。
  • publish(event_name: string, value: any): 发布事件。

示例代码

以下是一个完整的示例代码,展示了如何在 Flutter 应用中使用 belatuk_pub_sub

import 'dart:io';
import 'dart:isolate';
import 'package:belatuk_pub_sub/isolate.dart';
import 'package:belatuk_pub_sub/belatuk_pub_sub.dart';

void main() async {
  // 创建一个服务器
  var adapter = IsolateAdapter();
  var server = Server([adapter]);

  // 注册客户端
  for (var i = 0; i < Platform.numberOfProcessors - 1; i++) {
    server.registerClient(ClientInfo('client$i'));
  }

  // 启动服务器
  server.start();

  // 创建隔离进程
  for (var i = 0; i < Platform.numberOfProcessors - 1; i++) {
    await Isolate.spawn(isolateMain, [i, adapter.receivePort.sendPort]);
  }

  // 也可以在主进程中运行客户端
  isolateMain([0, adapter.receivePort.sendPort]);
}

void isolateMain(List args) {
  // 创建一个客户端
  var client = IsolateClient('client${args[0]}', args[1] as SendPort);

  // 订阅事件
  client.subscribe('user::logged_in').then((sub) {
    // 监听事件
    sub.listen((msg) {
      print('Logged in: $msg');
    });
  });

  // 发布事件
  client.publish('user::logged_in', 'User1');
}

更多关于Flutter事件发布订阅插件belatuk_pub_sub的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter事件发布订阅插件belatuk_pub_sub的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何使用Flutter事件发布订阅插件belatuk_pub_sub的代码案例。这个插件允许你在Flutter应用中实现事件的总线模式,让不同部分的应用能够发布和订阅事件。

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

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

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

下面是一个简单的示例,展示如何使用belatuk_pub_sub进行事件的发布和订阅。

1. 创建一个事件类

首先,创建一个事件类。这个类可以是任何Dart类,但为了演示目的,我们创建一个简单的CustomEvent类:

class CustomEvent {
  final String message;

  CustomEvent(this.message);
}

2. 设置事件总线

接下来,我们需要设置事件总线。通常,你会在应用的一个全局位置(比如main.dart)初始化这个总线:

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

void main() {
  final pubSub = PubSub<CustomEvent>();

  runApp(MyApp(pubSub: pubSub));
}

class MyApp extends StatelessWidget {
  final PubSub<CustomEvent> pubSub;

  MyApp({required this.pubSub});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomeScreen(pubSub: pubSub),
    );
  }
}

3. 发布事件

在应用的某个部分,你可以发布事件。例如,在一个按钮点击事件中:

import 'package:flutter/material.dart';

class PublisherScreen extends StatelessWidget {
  final PubSub<CustomEvent> pubSub;

  PublisherScreen({required this.pubSub});

  void _publishEvent() {
    CustomEvent event = CustomEvent("Hello, this is a custom event!");
    pubSub.publish(event);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Event Publisher')),
      body: Center(
        child: ElevatedButton(
          onPressed: _publishEvent,
          child: Text('Publish Event'),
        ),
      ),
    );
  }
}

4. 订阅事件

在另一个部分,你可以订阅这个事件并处理它:

import 'package:flutter/material.dart';

class SubscriberScreen extends StatefulWidget {
  final PubSub<CustomEvent> pubSub;

  SubscriberScreen({required this.pubSub});

  @override
  _SubscriberScreenState createState() => _SubscriberScreenState();
}

class _SubscriberScreenState extends State<SubscriberScreen> {
  String? _eventMessage;

  @override
  void initState() {
    super.initState();
    widget.pubSub.subscribe((event) {
      setState(() {
        _eventMessage = event.message;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Event Subscriber')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('Received Event Message: $_eventMessage'),
          ],
        ),
      ),
    );
  }
}

5. 组合屏幕

最后,将发布者和订阅者屏幕组合在一起,比如在一个导航器中:

import 'package:flutter/material.dart';

class HomeScreen extends StatelessWidget {
  final PubSub<CustomEvent> pubSub;

  HomeScreen({required this.pubSub});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Event Bus Demo')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ElevatedButton(
              onPressed: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => PublisherScreen(pubSub: pubSub)),
                );
              },
              child: Text('Go to Publisher'),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => SubscriberScreen(pubSub: pubSub)),
                );
              },
              child: Text('Go to Subscriber'),
            ),
          ],
        ),
      ),
    );
  }
}

现在,当你运行应用并导航到发布者屏幕,点击“Publish Event”按钮后,再导航到订阅者屏幕,你应该能看到接收到的事件消息。

这个示例展示了如何使用belatuk_pub_sub插件在Flutter应用中实现事件发布和订阅的基本机制。你可以根据需要扩展和修改这个示例以适应你的具体需求。

回到顶部