Flutter事件发布订阅插件belatuk_pub_sub的使用
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_2
和 package: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
更多关于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应用中实现事件发布和订阅的基本机制。你可以根据需要扩展和修改这个示例以适应你的具体需求。