Flutter数据流管理插件riptide的使用方法详解

Flutter数据流管理插件riptide的使用

Riptide Dart Port

pub package pub points package publisher

Riptide Dart Port 是 Tom Weiland 开发的轻量级网络库 Riptide 的 Dart 端口。此端口提供了使用 Riptide 协议建立客户端和服务器连接的功能。

兼容性

该端口最近一次测试时与 Riptide 的 Commit 945e4a0 版本兼容,时间为 2024 年 1 月 29 日。

注意: Riptide 本身不支持向后兼容。此库目前仅适用于 Riptide 版本 v2.1.2v2.2.0

旧版本(pub 0.0.3)仍可与 Riptide v2.0.0 兼容,但功能有限(如缺少 TCP 支持)。有关详细信息,请参阅 changelog

重要说明

Dart 语言与 C# 在某些关键方面有所不同。

  • Dart 中没有函数重载。因此,在消息类中会有许多不同的函数名。
  • Dart 中没有 ulong 类型。C# 的 longs 是 64 位有符号值,而 Dart 的 int 值也是 64 位有符号值。long 可以在 Dart 中无问题地表示为 int。不幸的是,Dart 中没有无符号 64 位类型。ulong 在 Dart 中的表示目前无法实现。当前,ulong 将被解析为 int。请注意这可能导致数据丢失。

其他语言中的兼容库

入门指南

API 大致与 Riptide 相同。

使用方法

启用日志记录
RiptideLogger.initialize(print, true);
创建新服务器
Server server = Server();
server.start(7777, 10); // 启动服务器,监听端口 7777,最大连接数为 10

// 定时器用于定期更新服务器
Timer.periodic(const Duration(milliseconds: 20), (timer) {
    server.update();
});

处理接收到的消息:

server.registerMessageHandler(ClientToServerId.serverTest.index, handleMessage);

void handleMessage(int clientID, Message message) {
    // 执行某些操作
}
创建新客户端
Client client = Client();
client.connect(InternetAddress("127.0.0.1"), 7777); // 连接到本地服务器

// 定时器用于定期更新客户端
Timer.periodic(const Duration(milliseconds: 20), (timer) {
    client.update();
});

处理接收到的消息:

client.registerMessageHandler(ServerToClientId.clientTest.index, handleMessage);

void handleMessage(Message message) {
    // 执行某些操作
}
发送消息
Message message = Message.createFromInt(MessageSendMode.reliable, ClientToServerId.serverTest.index);
message.addString("Hello World!");

client.send(message);
server.sendToAll(message);

多线程服务器/客户端

建议将整个服务器/客户端代码执行放在单独的隔离区中以提高性能。该库提供了轻量级的隔离实现。

将以下代码从

Server server = Server();
server.start(7777, 10);

Timer.periodic(const Duration(milliseconds: 20), (timer) {
    server.update();
});

改为

MultiThreadedServer mtServer = MultiThreadedServer();
mtServer.start(7777, 10, loggingEnabled: true);

或将以下代码从

Client client = Client();
client.connect(InternetAddress("127.0.0.1"), 7777);

Timer.periodic(const Duration(milliseconds: 20), (timer) {
    client.update();
});

改为

MultiThreadedClient mtClient = MultiThreadedClient();
mtClient.connect(InternetAddress("127.0.0.1"), 7777, loggingEnabled: true);

如果要使用其他传输方式,可以在构造函数调用时传递参数。

例如:

MultiThreadedClient mtClient = MultiThreadedClient(transportType: MultiThreadedTransportType.tcp);
mtClient.connect(InternetAddress("127.0.0.1"), 7777, loggingEnabled: true);

额外提示

如果您正在使用 Android,请确保在 AndroidManifest.xml 文件中启用互联网权限。

<android/app/src/main/AndroidManifest.xml> 添加以下内容:

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    ...
    <uses-permission android:name="android.permission.INTERNET"/>
    ...
</manifest>

如果您使用的是 Android 模拟器并使用 localhost,请注意应使用 IP 地址 10.0.2.2 而不是 localhost。

低级传输方式

该库支持以下低级传输方式:

贡献

欢迎贡献,尤其是了解低级 UDP/TCP 套接字和隔离的人。

许可证

此项目受 MIT 许可证保护。更多信息请参阅 LICENSE.md。版权所有 © 2024 VISUS,斯图加特大学。


示例代码

以下是一个完整的示例代码,展示了如何创建客户端和服务器,并发送消息。

import 'dart:io';

import 'package:riptide/riptide.dart';

enum ClientToServerId { serverTest }

enum ServerToClientId { clientTest }

void createClient() {
  Client client = Client();
  client.connect(InternetAddress('127.0.0.1'), 7777); // 连接到本地服务器

  client.registerMessageHandler(ServerToClientId.clientTest.index,
      (Message message) {
    print(message);
  });

  client.clientConnected.subscribe((args) {
    // 连接成功后发送测试消息到服务器
    Message message = Message.createFromInt(
        MessageSendMode.reliable, ClientToServerId.serverTest.index);
    message.addString('Hello Server!');
    client.send(message);
  });
}

void createServer() {
  Server server = Server();
  server.start(7777, 10); // 启动服务器,监听端口 7777,最大连接数为 10

  server.registerMessageHandler(ClientToServerId.serverTest.index,
      (fromClientID, message) {
    print("received message from client $fromClientID");
  });

  server.clientConnected.subscribe((args) {
    // 每当有新的客户端连接时,发送测试消息到该客户端
    Message message = Message.createFromInt(
        MessageSendMode.reliable, ServerToClientId.clientTest.index);
    message.addString('Hello Client!');
    server.send(message, args!.client.id);
  });
}

void main() {
  createClient();
  createServer();

  // 定时器用于定期更新客户端和服务器
  Timer.periodic(const Duration(milliseconds: 20), (timer) {
    client.update();
    server.update();
  });
}

更多关于Flutter数据流管理插件riptide的使用方法详解的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter数据流管理插件riptide的使用方法详解的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter开发中,数据流管理是一个非常重要的部分,尤其是在处理复杂的状态管理和异步数据流时。假设riptide是一个与数据流相关的插件,以下是一个基于数据流管理的使用示例和指南。请注意,由于riptide的具体功能未知,以下内容是基于常见的数据流管理模式的假设。

假设功能

假设riptide是一个用于管理数据流的Flutter插件,类似于rxdartflutter_bloc,它可以帮助开发者更方便地处理数据流、状态管理和异步操作。

1. 安装插件

首先,你需要在pubspec.yaml文件中添加riptide插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  riptide: ^1.0.0  # 假设版本号为1.0.0

然后运行flutter pub get来安装插件。

2. 创建数据流

假设riptide提供了StreamController或类似的功能来创建和管理数据流。以下是一个简单的示例:

import 'package:riptide/riptide.dart';

class CounterBloc {
  final _counterController = StreamController<int>();
  Stream<int> get counterStream => _counterController.stream;

  int _count = 0;

  void increment() {
    _count++;
    _counterController.sink.add(_count);
  }

  void dispose() {
    _counterController.close();
  }
}

3. 在UI中使用数据流

在Flutter中,你可以使用StreamBuilder来监听数据流并在UI中更新数据。

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: CounterPage(),
    );
  }
}

class CounterPage extends StatefulWidget {
  @override
  _CounterPageState createState() => _CounterPageState();
}

class _CounterPageState extends State<CounterPage> {
  final CounterBloc _counterBloc = CounterBloc();

  @override
  void dispose() {
    _counterBloc.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Riptide Counter'),
      ),
      body: Center(
        child: StreamBuilder<int>(
          stream: _counterBloc.counterStream,
          initialData: 0,
          builder: (context, snapshot) {
            return Text(
              'Count: ${snapshot.data}',
              style: Theme.of(context).textTheme.headline4,
            );
          },
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          _counterBloc.increment();
        },
        child: Icon(Icons.add),
      ),
    );
  }
}

4. 处理复杂数据流

假设riptide还提供了一些高级功能,比如流转换、错误处理、流合并等。你可以使用这些功能来更灵活地处理数据流。

import 'package:riptide/riptide.dart';

class ComplexBloc {
  final _inputController = StreamController<String>();
  final _outputController = StreamController<String>();

  ComplexBloc() {
    _inputController.stream
        .map((input) => input.toUpperCase())  // 示例:转换为大写
        .listen(_outputController.sink.add);
  }

  Stream<String> get outputStream => _outputController.stream;

  void addInput(String input) {
    _inputController.sink.add(input);
  }

  void dispose() {
    _inputController.close();
    _outputController.close();
  }
}
回到顶部