Flutter类型化消息处理插件typed_messages的使用
Flutter类型化消息处理插件typed_messages的使用
消息(Messages)
消息是一段可以在节点之间共享的信息。
让我们定义一个消息:
class ClientInfoMessage extends Message {
const ClientInfoMessage(this.name, this.avatar, this.clientId)
: assert(
name.length <= 20,
'client info name can not exceed 20 bytes : ${name.length}',
);
final int clientId; // 20 bytes Uint
final String name; // 字符长度在[0, 20]范围内
final int avatar; // 2 bytes Uint
}
原型(Prototypes)
原型用于在发送前对消息进行编码,并验证和解码传入的消息。
const int kClientInfoMessageId = 0;
// 定义或分配原型到__MessagesPrototypes__单例
IMessagePrototype.definePrototype(const ClientInfoMessagePrototype());
class ClientInfoMessagePrototype implements IMessagePrototype<ClientInfoMessage> {
const ClientInfoMessagePrototype();
[@override](/user/override)
Uint8List encode(ClientInfoMessage message) {
final writer = BytesWriter(22 + message.name.length);
writer.writeSingleByte(kClientInfoMessageId); // 写入消息ID
writer.writeSingleByte(message.name.length); // 写入名称长度
writer.writeText(message.name); // 写入名称
writer.writeUint(message.avatar, 2); // 写入头像
writer.writeUint(message.clientId, 20); // 写入客户端ID
return writer.toBuffer(); // 返回字节列表
}
[@override](/user/override)
ClientInfoMessage decode(Uint8List bytes) {
final reader = BytesReader(bytes);
final int nameLength = reader.readSingleByte(1); // 读取名称长度
final String name = reader.readText(2, nameLength); // 读取名称
final int avatar = reader.readUint(2 + nameLength, 2); // 读取头像
final int id = reader.readUint(4 + nameLength, 20); // 读取客户端ID
return ClientInfoMessage(name, avatar, id); // 返回解码后的消息
}
[@override](/user/override)
bool validate(Uint8List bytes) {
final reader = BytesReader(bytes);
if (reader.length < 22 || reader.length > 42) return false; // 验证字节长度
final int id = reader.readSingleByte(0); // 读取消息ID
final int nameLength = reader.readSingleByte(1); // 读取名称长度
return id == kClientInfoMessageId && nameLength >= 0 && nameLength <= 20; // 验证消息ID和名称长度
}
}
使用(Usage)
现在我们已经创建了ClientInfoMessage
类并定义了其原型ClientInfoMessagePrototype
,使用IMessagePrototype.definePrototype
方法。
我们有两种方式来编码和解码数据:
方法1:使用Message
抽象类
final message = ClientInfoMessage("My Client", 0, 568978596);
final Uint8List bytes = Message.encode(message); // 编码消息
final ClientInfoMessage? decodedMessage = Message.decode(bytes); // 解码消息
方法2:使用MessagesPrototypes
单例和原型直接
final instance = MessagesPrototypes.instance;
final message = ClientInfoMessage("My Client", 0, 568978596);
// 编码
final Uint8List? bytes = instance.encodeMessage(message);
// 解码
final ClientInfoMessage? decodedMessage = instance.decodeBytes(bytes!);
// 使用定义的原型
final IMessagePrototype<ClientInfoMessage>? prototype = instance.findPrototypeByMessageType<ClientInfoMessage>();
prototype.encode(message); // 编码消息
prototype.decode(bytes!); // 解码消息
prototype.validate(bytes!); // 验证消息
示例代码
import 'dart:typed_data';
import 'package:typed_messages/typed_messages.dart';
const int kClientInfoMessageId = 0;
class ClientInfoMessage extends Message {
const ClientInfoMessage(this.name, this.avatar, this.clientId)
: assert(
name.length >= 0 && name.length <= 20,
'name length must be in range [0, 20] characters',
);
final String name;
final int avatar;
final int clientId;
}
class ClientInfoMessagePrototype
implements IMessagePrototype<ClientInfoMessage> {
const ClientInfoMessagePrototype();
[@override](/user/override)
Uint8List encode(ClientInfoMessage message) {
final writer = BytesWriter(22 + message.name.length);
writer.writeSingleByte(kClientInfoMessageId);
writer.writeSingleByte(message.name.length);
writer.writeText(message.name);
writer.writeUint(message.avatar, 2);
writer.writeUint(message.clientId, 20);
return writer.toBuffer();
}
[@override](/user/override)
ClientInfoMessage decode(Uint8List bytes) {
final reader = BytesReader(bytes);
final int nameLength = reader.readSingleByte(1);
final String name = reader.readText(2, nameLength);
final int avatar = reader.readUint(2 + nameLength, 2);
final int clientId = reader.readUint(4 + nameLength, 20);
return ClientInfoMessage(name, avatar, clientId);
}
[@override](/user/override)
bool validate(Uint8List bytes) {
final reader = BytesReader(bytes);
if (reader.length < 22 || reader.length > 42) return false;
final int id = reader.readSingleByte(0);
final int nameLength = reader.readSingleByte(1);
return id == kClientInfoMessageId && nameLength >= 0 && nameLength <= 20;
}
}
void main() {
IMessagePrototype.definePrototype(const ClientInfoMessagePrototype());
final message = ClientInfoMessage("My Client", 0, 568978596);
Uint8List bytes;
ClientInfoMessage? decodedMessage;
// 编码
bytes = Message.encode(message);
// 解码
decodedMessage = Message.decode<ClientInfoMessage>(bytes);
// 使用MessagesPrototypes实例
final instance = MessagesPrototypes.instance;
final IMessagePrototype<ClientInfoMessage>? prototype =
instance.findPrototypeByMessageType<ClientInfoMessage>();
bytes = prototype!.encode(message);
final bool isValidBytes = prototype.validate(bytes);
decodedMessage = prototype.decode(bytes);
}
更多关于Flutter类型化消息处理插件typed_messages的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter类型化消息处理插件typed_messages的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
typed_messages
是一个用于 Flutter 的类型化消息处理插件,它允许你在 Flutter 应用中发送和接收类型化的消息。这个插件特别适用于需要在不同组件或模块之间进行通信的场景。通过使用 typed_messages
,你可以确保消息的类型安全,并减少运行时错误。
安装
首先,你需要在 pubspec.yaml
文件中添加 typed_messages
依赖:
dependencies:
flutter:
sdk: flutter
typed_messages: ^0.1.0 # 请检查最新版本
然后运行 flutter pub get
来安装依赖。
基本用法
1. 定义消息类型
首先,你需要定义消息的类型。你可以通过继承 TypedMessage
来创建自定义的消息类型。
import 'package:typed_messages/typed_messages.dart';
class MyMessage extends TypedMessage {
final String content;
MyMessage(this.content);
}
2. 创建消息处理器
接下来,你需要创建一个消息处理器来处理特定类型的消息。你可以通过继承 TypedMessageHandler
来实现。
class MyMessageHandler extends TypedMessageHandler<MyMessage> {
@override
void handle(MyMessage message) {
print('Received message: ${message.content}');
}
}
3. 注册消息处理器
然后,你需要将消息处理器注册到 TypedMessageDispatcher
中。
void main() {
final dispatcher = TypedMessageDispatcher();
dispatcher.registerHandler(MyMessageHandler());
}
4. 发送消息
最后,你可以通过 TypedMessageDispatcher
发送消息。
void main() {
final dispatcher = TypedMessageDispatcher();
dispatcher.registerHandler(MyMessageHandler());
// 发送消息
dispatcher.dispatch(MyMessage('Hello, World!'));
}
高级用法
处理多个消息类型
你可以注册多个消息处理器来处理不同类型的消息。
class AnotherMessage extends TypedMessage {
final int number;
AnotherMessage(this.number);
}
class AnotherMessageHandler extends TypedMessageHandler<AnotherMessage> {
@override
void handle(AnotherMessage message) {
print('Received number: ${message.number}');
}
}
void main() {
final dispatcher = TypedMessageDispatcher();
dispatcher.registerHandler(MyMessageHandler());
dispatcher.registerHandler(AnotherMessageHandler());
// 发送不同类型的消息
dispatcher.dispatch(MyMessage('Hello, World!'));
dispatcher.dispatch(AnotherMessage(42));
}
异步消息处理
如果你的消息处理逻辑是异步的,你可以在 handle
方法中使用 async
和 await
。
class AsyncMessageHandler extends TypedMessageHandler<MyMessage> {
@override
Future<void> handle(MyMessage message) async {
await Future.delayed(Duration(seconds: 1));
print('Async message received: ${message.content}');
}
}
取消注册处理器
如果你不再需要某个消息处理器,可以将其取消注册。
void main() {
final dispatcher = TypedMessageDispatcher();
final handler = MyMessageHandler();
dispatcher.registerHandler(handler);
// 取消注册处理器
dispatcher.unregisterHandler(handler);
}