Flutter高速数据传输插件uhst的使用
Flutter高速数据传输插件uhst的使用
User Hosted Secure Transmission (UHST)
是一个用于 Flutter 应用的 Dart 客户端库。它支持以下功能:
- 从客户端发送消息并监听主机广播的消息。
- 主机可以广播消息。
- 主机可以监听来自多个客户端的消息。
关于
UHST 是用户托管安全传输框架的客户端库。它可以实现以下功能:
- 发送消息从客户端到主机,并监听主机广播的消息。
- 主机广播消息。
- 主机监听来自多个客户端的消息。
你可以查看 GitHub 上的实现示例 和源码。
请注意当前版本的限制:
- 它只支持字符串类型的消息。
- 需要一个实现了 UHST 协议的服务器。你可以查看一个现成的服务器示例 GitHub。
支持和讨论
请加入我们的 Gitter 或者在 StackOverflow 上提问。
使用
假设你已经加载了库,首先创建一个新的实例:
var uhst = UHST();
你可以查阅文档了解更多可以传递的选项(包括你的自己的 Relay 服务器 URL、WebRTC 配置等)。
主机
在 UHST 中,主机是一个每个其他对等体连接的节点。这个概念类似于多人游戏中监听服务器的角色。
请确保在重新连接到另一个主机之前关闭之前的连接。
创建一个新的主机的最简单方法如下:
var host = uhst.host("testHost");
host?.disconnect();
host
?..onReady(handler: ({required String hostId}) {
setState(() {
hostMessages.add('Host Ready! Using $hostId');
print('host is ready!');
_hostIdController.text = hostId;
});
})
..onException(handler: ({required dynamic exception}) {
print('exception received! $exception');
if (exception is HostIdAlreadyInUse) {
// 如果刷新页面,这是预期的情况
// 连接仍然在 Relay 上
// 只需等待即可
setState(() {
hostMessages
.add('HostId already in use, retrying in 15 seconds...!');
});
} else {
setState(() {
hostMessages.add(exception.toString());
});
}
})
..onConnection(handler: ({required UhstSocket uhstSocket}) {
uhstSocket.onDiagnostic(handler: ({required String message}) {
setState(() {
hostMessages.add(message);
});
});
uhstSocket.onMessage(handler: ({required message}) {
setState(() {
hostMessages
.add("Host received: $message");
host?.broadcastString(message: message);
});
});
uhstSocket.onOpen(handler: () {
// uhstSocket.sendString(message: 'Host sent message!');
});
});
}
注意,请求的主机 ID 可能不会被信号服务器接受,你应该始终在连接到主机时使用 hostId
接收到的 ready
事件后的 hostId
。
客户端
要从另一个浏览器连接到主机,请使用你在 onReady
事件期间接收的相同 hostId
。
请确保在重新连接到另一个主机之前关闭之前的连接。
var client = uhst.join("testHost");
client?.close();
client
?..onOpen(handler: () {
setState(() {
client?.sendString(message: 'Hello host!');
});
})
..onMessage(handler: ({required message}) {
setState(() {
clientMessages.add('Client received: $message');
});
})
..onException(handler: ({required dynamic exception}) {
if (exception is InvalidHostId || exception is InvalidClientOrHostId) {
setState(() {
clientMessages.add('Invalid hostId!');
});
} else {
setState(() {
clientMessages.add(exception.toString());
});
}
})
..onDiagnostic(handler: ({required String message}) {
setState(() {
clientMessages.add(message);
});
});
UHST 客户端接口类似于 HTML5 WebSocket 接口,但与专用服务器不同的是,一个对等体充当主机供其他对等体加入。
一旦客户端和主机连接,它们就可以异步交换消息。任意数量的客户端可以连接到同一个主机,但是客户端不能互相发送消息,只能与主机通信。
清理
记得调用 .dispose()
来取消所有订阅并断开主机套接字与服务器、客户端与主机的连接。
在 Flutter 中,你可以在 dispose
覆盖方法中添加这样的方法:
[@override](/user/override)
void dispose() {
client?.dispose();
host?.dispose();
super.dispose();
}
完整示例代码
以下是完整的示例代码,展示了如何使用 UHST 插件进行数据传输:
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:uhst/uhst.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
[@override](/user/override)
Widget build(BuildContext context) => MaterialApp(
title: 'Flutter UHST Example',
theme:
ThemeData(primarySwatch: Colors.blue, brightness: Brightness.dark),
home: const MyHomePage(title: 'Flutter UHST Example'),
);
}
class MyHomePage extends StatefulWidget {
const MyHomePage({
required this.title,
Key? key,
}) : super(key: key);
final String title;
[@override](/user/override)
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final List<String> hostMessages = [];
final List<String> clientMessages = [];
UHST? uhst;
UhstHost? host;
UhstSocket? client;
final TextEditingController _hostIdController = TextEditingController();
Future<void> startHosting() async {
initUHST();
host?.disconnect();
host = uhst?.host();
host
?..onReady(handler: ({required hostId}) {
hostMessages.add('Host Ready! Using hostId $hostId');
print('host is ready!');
_hostIdController.text = hostId;
setState(() {});
})
..onException(handler: ({required dynamic exception}) {
if (exception is RelayException) {
hostMessages.add('disconneted! $exception');
} else {
hostMessages.add('exception received! $exception');
}
setState(() {});
})
..onClose(handler: ({required hostId}) {
hostMessages.add('Host $hostId disconnected');
setState(() {});
})
..onConnection(handler: ({required UhstSocket uhstSocket}) {
uhstSocket
..onDiagnostic(handler: ({required message}) {
hostMessages.add(message);
setState(() {});
})
..onMessage(handler: ({required message}) {
hostMessages
.add('Host received: $message from ${uhstSocket.remoteId}');
setState(() {});
host?.broadcastString(message: message);
})
..onOpen(handler: () {
hostMessages.add('Client ${uhstSocket.remoteId} connected');
setState(() {});
})
..onClose(handler: ({required hostId}) {
hostMessages.add('Client $hostId disconected');
setState(() {});
});
});
}
Future<void> stopHosting() async => host?.disconnect();
void initUHST() {
uhst ??= UHST(
debug: true,
// relayUrl: 'http://127.0.0.1:3000',
);
}
Future<void> join() async {
initUHST();
client?.close();
client = uhst?.join(hostId: _hostIdController.text);
client
?..onException(handler: ({required dynamic exception}) {
final text = '[EXCEPION]: ${exception.toString()}';
if (exception is InvalidHostId || exception is InvalidClientOrHostId) {
clientMessages.add('[EXCEPION]: Invalid hostId!');
} else if (exception is HostDisconnected) {
clientMessages.add(text);
} else {
clientMessages.add(text);
}
setState(() {});
})
..onDiagnostic(handler: ({required message}) {
clientMessages.add(message);
setState(() {});
})
..onOpen(handler: () {
clientMessages.add('Client connected to host: ${client?.remoteId}');
setState(() {});
})
..onClose(handler: ({required hostId}) {
clientMessages.add('Connection to host $hostId dropped.');
setState(() {});
})
..onMessage(handler: ({required message}) {
clientMessages.add('Client received: $message');
setState(() {});
});
}
Future<void> diconnect() async => client?.close();
[@override](/user/override)
void dispose() {
client?.dispose();
host?.dispose();
super.dispose();
}
[@override](/user/override)
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Row(
children: [
Flexible(
flex: 2,
child: Material(
elevation: 4,
child: Container(
padding: const EdgeInsets.all(10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Center(
child: Text('Host'),
),
const Divider(height: 22),
TextField(
decoration: const InputDecoration(labelText: 'Host id'),
controller: _hostIdController,
),
const SizedBox(height: 20),
Wrap(
children: [
const Text('Host actions:'),
...[
TextButton(
onPressed: startHosting,
child: const Text('Start hosting'),
),
TextButton(
onPressed: stopHosting,
child: const Text('Finish hosting'),
),
TextButton(
onPressed: () {
hostMessages.clear();
setState(() {});
},
child: const Text('Clear host messages'),
),
].map(
(w) => Padding(
padding: const EdgeInsets.only(left: 20),
child: w,
),
)
],
),
const Divider(
thickness: 1,
),
const SizedBox(height: 20),
const Center(
child: Text('Host chat & debug messages'),
),
const SizedBox(height: 20),
Expanded(
child: ListView.builder(
itemBuilder: (context, index) =>
Text(hostMessages[index]),
itemCount: hostMessages.length,
),
)
],
),
),
),
),
Flexible(
flex: 2,
child: Padding(
padding: const EdgeInsets.all(10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Center(child: Text('Client')),
const Divider(height: 22),
Wrap(
children: [
const Text('Client actions:'),
...[
TextButton(
onPressed: join,
child: const Text('Join a host'),
),
TextButton(
onPressed: diconnect,
child: const Text('Leave a host'),
),
TextButton(
onPressed: () {
clientMessages.clear();
setState(() {});
},
child: const Text('Clear client messages'),
),
].map(
(w) => Padding(
padding: const EdgeInsets.only(left: 20),
child: w,
),
)
],
),
const Divider(height: 22),
TextField(
controller: _hostIdController,
decoration: InputDecoration(
labelText: 'Client messsage',
suffix: IconButton(
icon: const Icon(Icons.send),
onPressed: () {
if (client == null) {
clientMessages.add(
'No client initialized! '
'Start hosting and join a host first',
);
}
client?.sendString(
message: _hostIdController.text);
_hostIdController.clear();
setState(() {});
},
),
),
),
const SizedBox(height: 20),
const Center(child: Text('Client chat and debug messages')),
const SizedBox(height: 20),
Expanded(
child: ListView.builder(
itemBuilder: (context, index) =>
Text(clientMessages[index]),
itemCount: clientMessages.length,
),
)
],
),
),
)
],
),
);
[@override](/user/override)
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties
..add(IterableProperty<String>('hostMessages', hostMessages))
..add(DiagnosticsProperty<UHST?>('uhst', uhst))
..add(DiagnosticsProperty<TextEditingController>('hostTextFieldController', _hostIdController))
..add(DiagnosticsProperty<UhstSocket?>('client', client))
..add(IterableProperty<String>('clientMessages', clientMessages))
..add(DiagnosticsProperty<UhstHost?>('host', host));
}
}
更多关于Flutter高速数据传输插件uhst的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter高速数据传输插件uhst的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何在Flutter项目中使用UHST(Ultra High-Speed Transfer)插件来实现高速数据传输的示例代码。UHST 插件允许开发者在Flutter应用中实现高效、快速的数据传输。
首先,确保你的Flutter开发环境已经配置好,然后你可以按照以下步骤来集成和使用UHST插件。
1. 添加依赖
在你的pubspec.yaml
文件中添加UHST插件的依赖:
dependencies:
flutter:
sdk: flutter
uhst: ^latest_version # 请替换为最新的版本号
然后运行flutter pub get
来安装依赖。
2. 初始化UHST
在你的Flutter应用中,你需要初始化UHST客户端。这通常在你的应用的主入口文件中完成,比如main.dart
。
import 'package:flutter/material.dart';
import 'package:uhst/uhst.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
late UhstClient uhstClient;
@override
void initState() {
super.initState();
// 初始化UHST客户端
uhstClient = UhstClient(
apiKey: 'YOUR_UHST_API_KEY', // 请替换为你的UHST API密钥
);
// 监听连接状态变化
uhstClient.onStatusChange.listen((status) {
print('UHST status changed: $status');
});
// 监听数据接收事件
uhstClient.onData.listen((data) {
print('Received data: ${String.fromCharCodes(data)}');
});
// 连接到UHST服务器(假设你已经有了房间ID)
uhstClient.connect('ROOM_ID').then((_) {
print('Connected to UHST room.');
}).catchError((error) {
print('Failed to connect: $error');
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('UHST Flutter Demo'),
),
body: Center(
child: Text('Check the console for UHST status and data updates.'),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
// 发送数据示例
String message = 'Hello, UHST!';
uhstClient.send(message.codeUnits);
},
tooltip: 'Send Data',
child: Icon(Icons.send),
),
),
);
}
@override
void dispose() {
// 断开连接并释放资源
uhstClient.disconnect();
super.dispose();
}
}
3. 运行应用
确保你的开发环境中已经配置好了必要的权限(比如网络访问权限),然后运行你的Flutter应用。
flutter run
注意事项
- API密钥:请确保你替换了
YOUR_UHST_API_KEY
为你的实际UHST API密钥。 - 房间ID:在
uhstClient.connect('ROOM_ID')
中替换ROOM_ID
为实际的房间ID,或者根据你的应用逻辑动态生成房间ID。 - 错误处理:在实际应用中,你应该添加更多的错误处理逻辑,以确保应用的健壮性。
- 权限:确保你的应用有适当的权限来访问网络。
这个示例展示了如何在Flutter应用中集成UHST插件,并进行基本的数据发送和接收操作。根据你的具体需求,你可能需要进一步定制和扩展这个示例。