Flutter进程间通信插件dart_ipc的使用
Flutter进程间通信插件dart_ipc的使用
dart_ipc简介
dart_ipc
是一个跨平台的 Dart 进程间通信(IPC)库,利用本地平台机制在进程之间提供高效的通信。它支持 Windows、Linux、macOS 和 Android 平台。
特性
- 跨平台:适用于 Windows、Linux、macOS 和 Android。
- 原生性能:在 Windows 上使用
Named pipe
,在 Unix 系统上使用Unix domain socket
。 - 简单API:与
socket
API 兼容。
安装
要安装 dart_ipc
插件,请在终端中运行以下命令:
dart pub add dart_ipc
使用示例
服务器端代码示例
import 'package:dart_ipc/dart_ipc.dart';
final serverSocket = await bind(path);
await for (final socket in serverSocket) {
print(socket);
socket.listen((data) {
// 打印接收到的数据
print(utf8.decode(data));
// 发送数据到客户端
socket.add(utf8.encode('Hello from Server'));
}, onDone: () {
print("Server Done");
}, onError: (e) {
print("Server Error: $e");
});
}
客户端代码示例
import 'package:dart_ipc/dart_ipc.dart';
final socket = await connect(path);
socket.listen((data) {
// 打印接收到的数据
print(utf8.decode(data));
}, onDone: () {
print("Client Done");
}, onError: (e) {
print("Client Error: $e");
});
for (var i = 0; i < 10; i++) {
// 发送数据到服务器
socket.add(utf8.encode("Hello from client2 $i"));
await Future.delayed(Duration(seconds: 1));
}
await socket.close();
JSON-RPC 集成示例
服务器端代码
import 'package:dart_ipc/dart_ipc.dart';
import 'package:json_rpc_2/json_rpc_2.dart';
import 'package:web_socket_channel/io.dart';
import 'package:web_socket_channel/web_socket_channel.dart';
void main() async {
final serverSocket = await bind(path);
final httpServer = HttpServer.listenOn(serverSocket);
final connectedChannels = httpServer
.transform(WebSocketTransformer())
.map(IOWebSocketChannel.new);
connectedChannels.listen(handleClient);
}
void handleClient(WebSocketChannel socket) {
var server = Server(socket.cast<String>());
var i = 0;
server.registerMethod('count', () {
return i++;
});
server.registerMethod('echo', (Parameters params) {
return params['message'].value;
});
server.registerMethod('subtract', (Parameters params) {
return params['minuend'].asNum - params['subtrahend'].asNum;
});
server.registerMethod('sort', (Parameters params) {
var list = params['list'].asList;
list.sort();
if (params['descendint'].asBoolOr(false)) {
return list.reversed;
} else {
return list;
}
});
const divideByZero = 1;
server.registerMethod('divide', (Parameters params) {
var divisor = params['divisor'].asNum;
if (divisor == 0) {
throw RpcException(divideByZero, 'Cannot divide by zero.');
}
return params['dividend'].asNum / divisor;
});
server.listen();
}
客户端代码
import 'package:dart_ipc/dart_ipc.dart';
import 'package:json_rpc_2/json_rpc_2.dart';
import 'package:web_socket_channel/io.dart';
import 'package:web_socket_channel/web_socket_channel.dart';
void main() async {
final httpClient = HttpClient()
..connectionFactory =
(Uri uri, String? proxyHost, int? proxyPort) {
final socket = connect(path);
return Future.value(
ConnectionTask.fromSocket(socket, () {}));
};
final socket = IOWebSocketChannel.connect("ws://localhost",
customClient: httpClient);
var client = Client(socket.cast<String>());
unawaited(client.listen());
var count = await client.sendRequest('count');
print('Count is $count');
var echo =
await client.sendRequest('echo', {'message': 'hello'});
print('Echo says "$echo"!');
client.sendNotification('count');
try {
await client
.sendRequest('divide', {'dividend': 2, 'divisor': 0});
} on RpcException catch (error) {
print('RPC error ${error.code}: ${error.message}');
}
}
平台支持
平台 | 实现 |
---|---|
Windows | Named pipe |
Linux | Unix domain socket |
macOS | Unix domain socket |
Android | Unix domain socket |
许可证
该项目采用 MIT 许可证 - 查看 LICENSE 文件了解详情。
完整示例 Demo
以下是完整的 Flutter 应用程序示例,包含服务器和客户端功能:
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:path/path.dart' as path;
import 'dart:async';
import 'package:dart_ipc/dart_ipc.dart';
import 'package:path_provider/path_provider.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
[@override](/user/override)
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
late String _path;
[@override](/user/override)
void initState() {
super.initState();
if (Platform.isWindows) {
_path = r"\\.\pipe\dart_ipc";
} else {
(() async {
_path =
path.join((await getTemporaryDirectory()).path, "dart_ipc.unix");
})();
}
}
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: Center(
child: Row(
children: [
TextButton(
onPressed: () async {
final serverSocket = await bind(_path);
await for (final socket in serverSocket) {
print(socket);
socket.listen((data) {
print(utf8.decode(data));
socket.add(utf8.encode('Hello from Server'));
}, onDone: () {
print("Server Done");
}, onError: (e) {
print("Server Error: $e");
});
}
},
child: Text("Server")),
TextButton(
onPressed: () async {
final socket = await connect(_path);
socket.listen((data) {
print(utf8.decode(data));
}, onDone: () {
print("Client Done");
}, onError: (e) {
print("Client Error: $e");
});
for (var i = 0; i < 10; i++) {
socket.add(utf8.encode("Hello from client1 $i"));
await Future.delayed(Duration(seconds: 1));
}
await socket.close();
},
child: Text("Client1")),
TextButton(
onPressed: () async {
final socket = await connect(_path);
socket.listen((data) {
print(utf8.decode(data));
}, onDone: () {
print("Client Done");
}, onError: (e) {
print("Client Error: $e");
});
for (var i = 0; i < 10; i++) {
socket.add(utf8.encode("Hello from client2 $i"));
await Future.delayed(Duration(seconds: 1));
}
await socket.close();
},
child: Text("Client2")),
],
),
),
),
);
}
}
更多关于Flutter进程间通信插件dart_ipc的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter进程间通信插件dart_ipc的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何在Flutter项目中使用dart_ipc
插件来实现进程间通信(IPC)的代码示例。dart_ipc
插件允许你在Flutter应用的不同隔离环境中进行通信,比如在不同的isolate之间。
首先,确保你已经在pubspec.yaml
文件中添加了dart_ipc
依赖:
dependencies:
flutter:
sdk: flutter
dart_ipc: ^最新版本号 # 请替换为当前最新版本号
然后运行flutter pub get
来安装依赖。
示例代码
主应用代码(main.dart)
import 'package:flutter/material.dart';
import 'package:dart_ipc/dart_ipc.dart';
import 'dart:isolate';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
static const platform = MethodChannel('com.example.myapp/channel');
IpcReceiver? receiver;
late IpcSender sender;
@override
void initState() {
super.initState();
// 启动一个Isolate并传递IpcSender
Isolate.spawn(entryPoint, null, onExit: _onIsolateExit)
.then((isolate) {
sender = IpcSender(isolate);
});
// 初始化IpcReceiver以监听来自Isolate的消息
receiver = IpcReceiver((message) {
print('Received message from isolate: $message');
});
}
@override
void dispose() {
receiver?.close();
super.dispose();
}
void _onIsolateExit(Isolate isolate, {int? exitCode, String? reason}) {
print('Isolate exited: $reason');
}
void sendMessageToIsolate(String message) {
sender.send(message);
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Flutter IPC Demo'),
),
body: Center(
child: ElevatedButton(
onPressed: () {
sendMessageToIsolate('Hello from main isolate!');
},
child: Text('Send Message'),
),
),
),
);
}
// Isolate的入口点
static void entryPoint(dynamic message) async {
IpcReceiver receiver = IpcReceiver((message) {
print('Received message from main: $message');
// 回复主Isolate
IpcSender.current!.send('Hello from secondary isolate!');
});
// 保持Isolate活跃以监听消息
await Future.delayed(Duration(days: 365));
}
}
解释
-
依赖添加:确保在
pubspec.yaml
中添加了dart_ipc
依赖。 -
主Isolate:
- 初始化
IpcReceiver
来监听来自其他Isolate的消息。 - 使用
Isolate.spawn
启动一个新的Isolate,并传递一个IpcSender
实例,以便主Isolate可以向新Isolate发送消息。
- 初始化
-
新Isolate:
- 在
entryPoint
函数中,初始化一个IpcReceiver
来监听来自主Isolate的消息。 - 使用
IpcSender.current!
发送回复消息给主Isolate。注意,IpcSender.current
只能在被dart_ipc
插件初始化的Isolate中使用。
- 在
-
消息发送:
- 在主Isolate中,点击按钮时通过
sender.send(message)
发送消息到新Isolate。 - 在新Isolate中,接收到消息后,通过
IpcSender.current!.send(message)
回复消息给主Isolate。
- 在主Isolate中,点击按钮时通过
-
资源管理:
- 在
dispose
方法中关闭IpcReceiver
以释放资源。
- 在
通过上述代码,你可以在Flutter应用中实现基本的进程间通信。请注意,dart_ipc
主要用于Dart isolates之间的通信,而不是操作系统级别的进程间通信。如果你需要进行跨操作系统的进程间通信,可能需要考虑其他方法或插件。