Flutter代理通信插件agent_dart的使用

Flutter代理通信插件agent_dart的使用

agent_dart

pub package GitHub license Discord

一个为Internet Computer构建的代理库,是一个用于dart和flutter应用的插件包。开发者可以使用它直接与Dfinity的区块链进行交互。

社区: https://discord.gg/aNzRuePmUY


目录

  1. 目录
  2. 前置条件
  3. 快速开始
  4. 动机
  5. 里程碑
  6. 文档
  7. 贡献
  8. 参考和相关项目
  9. 常见问题

前置条件

  • Flutter 版本在 agent_dart/pubspec.yaml
  • CMake v3.2.0 或更高版本
  • Xcode (10.12) 或更高版本(运行在macOS或iOS上)
  • Android NDK 版本 21.4.7075529 (运行在Android上)
  • Rust 版本 1.51
  • Node.js v15.0 或更高版本,待定

快速开始

  1. 克隆git仓库

  2. 安装前置条件,确保运行以下命令无错误:

    flutter doctor -v
    
  3. 运行示例,遵循 example 文件夹下的说明:

    cd example
    flutter run
    
  4. 运行测试

    flutter test
    

动机

Internet Computer由区块链驱动,并且其主要影响在于将Web应用程序真正去中心化。然而,我们正处于移动互联网时代,即使我们可以使用Safari或Chrome在手机上浏览网页,但大多数普通人,不是加密爱好者,更可能使用原生移动应用。因此,吸引这些人使用Internet Computer的Dapps非常重要,这需要提供稳定、快速并且完全集成到Dfinity区块链的应用程序。首先,我们必须让移动原生应用工作。

agent-rsagent-js 是实际的低级客户端SDK,就像Ethereum生态系统中的 ether.jsweb3.js。此库旨在移植并复制它们的功能。该库主要用于移动应用连接canisters,而不是部署合约(如果你想这样做,可以直接使用dart)。

我们已经尽力迁移了大部分接口样式,就像JavaScript版本一样,但由于不同编程语言之间的限制和差异,我们将尽可能详细地记录这些差异。


里程碑

里程碑1:核心功能/库迁移

  • agent,核心库,包含加密和编码/解码方法,封装了HTTP调用/查询,用于与canister交互。
  • auth_client,一个用于flutter的弹出窗口,用于从身份提供商(例如Internet Identity)获取认证。
  • authentication,支持 auth_client 的库。
  • candid,candid库,用于编码/解码candid数据类型,并在dart-lang中使用。
  • principal,principal库,用于生成各种用途的principal。
  • protobuf,protobuf库,用于与 rosetta-node 在提交/查询交易时进行交互。
  • utils,通用工具库,包括有用的扩展方法等。
  • wallet,钱包库,集成了signer、rosetta和key-smith。

里程碑2:增强构建工具和更多示例应用

里程碑3:文档和社区驱动开发


文档

参考pub.dev上的文档

文档计划

一个独立的文档站点,提供用Flutter/Dart编写的Dfinity Dapps指南。


贡献

通过贡献到agent_dart,你同意你的贡献将根据MIT许可证发布。

  1. 克隆此库并添加自己的分支

    {github_id}/{feat|fix|test|dep}-{detail}
    
  2. 安装前置条件

  3. 为所有受支持的平台(macOS、iOS、Android、Windows、Linux)构建rust依赖

    $ sh ./scripts/clean && ./scripts/init.sh && ./scripts/build.sh
    
  4. 启动示例

    先阅读说明,然后运行:

    $ cd example
    $ flutter run
    
  5. 测试(单元测试和集成测试)

    $ flutter test
    
  6. **提交并发起拉取请求,过程目前待定。我们将使用CI自动化。


参考和相关项目


常见问题

构建iOS/macOS的rust库

  • 所有的rust方法必须写在 SwiftAgentDartPlugin.swift 中,以避免由XCode最新发行版树摇导致的问题。

  • 当此仓库达到1.0.0时,应相应更改 agent_dart_podspec

  • 在MacOS的M1芯片组上,请安装 rosetta 2

    $ sudo softwareupdate --install-rosetta --agree-to-license
    

iOS和macOS网络问题

  • 如果你在运行示例或构建flutter应用时遇到问题:

    [macOS] SocketException: Connection failed (OS Error: Operation not permitted, errno = 1)
    
  • 进入 macos/Runner/ios/Runner

  • 编辑 DebugProfile.entitlementsReleaseProfile.entitlements,添加以下内容:

    <key>com.apple.security.network.client</key>
    <true/>
    

示例代码

import 'package:flutter/material.dart';

import 'counter.dart';
import 'init.dart';

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

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  [@override](/user/override)
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  int _count = 0;
  bool _loading = false;
  String _status = "";

  late Counter _counter;
  final _scaffoldKey = GlobalKey<ScaffoldState>();

  [@override](/user/override)
  void initState() {
    super.initState();

    initCounter();
    loading(true);
    readCount();
  }

  void initCounter() {
    _counter = AgentFactory.create(
      canisterId: "qaa6y-5yaaa-aaaaa-aaafa-cai",
      url: 
      "http://localhost:8000", // 对于Android模拟器,请使用10.0.2.2作为端点
      idl: idl,
    ).hook(Counter());
  }

  void loading(bool state) {
    setState(() {
      _loading = state;
    });
  }

  void readCount() async {
    int c = await _counter.count();
    loading(false);
    setState(() {
      _count = c;
    });
  }

  void increase() async {
    loading(true);
    await _counter.add();
    readCount();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        key: _scaffoldKey,
        appBar: AppBar(
          title: const Text('Dfinity flutter Dapp'),
        ),
        body: Center(
          child: Column(mainAxisAlignment: MainAxisAlignment.center, children: [
            Text(_loading ? 'loading contract count' : '$_count'),
            Container(
              height: 30,
            ),
            Container(
              height: 30,
            ),
            Text(_status.isEmpty ? "Please Login 👆" : _status),
            Container(
              height: 30,
            ),
          ]),
        ),
        floatingActionButton: FloatingActionButton(
          child: const Icon(Icons.add),
          onPressed: () async {
            increase();
          },
        ),
      ),
    );
  }
}

更多关于Flutter代理通信插件agent_dart的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter代理通信插件agent_dart的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,关于Flutter代理通信插件agent_dart的使用,下面是一个基本的代码示例,展示如何在Flutter应用中集成和使用该插件。请注意,agent_dart插件的具体用法和功能可能会根据插件版本和具体需求有所不同,因此请参考最新的官方文档以获取最准确的信息。

首先,确保在pubspec.yaml文件中添加agent_dart依赖:

dependencies:
  flutter:
    sdk: flutter
  agent_dart: ^最新版本号  # 替换为当前最新版本号

然后,运行flutter pub get来安装依赖。

接下来,我们将展示如何在Flutter应用中初始化并使用agent_dart插件进行代理通信。以下是一个简化的示例,展示了如何发送和接收消息。

import 'package:flutter/material.dart';
import 'package:agent_dart/agent_dart.dart';  // 导入agent_dart包

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Agent Dart Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  Agent? _agent;

  @override
  void initState() {
    super.initState();
    // 初始化Agent实例
    _agent = Agent.instance;

    // 设置消息接收回调
    _agent?.onMessageReceived?.listen((message) {
      print("Received message: $message");
      // 在这里处理接收到的消息
    });

    // 可选:设置连接状态变化回调
    _agent?.onConnectionStateChanged?.listen((state) {
      print("Connection state changed: $state");
      // 在这里处理连接状态变化
    });

    // 连接到代理服务器(假设代理服务器已经启动并在监听)
    _connectToAgent();
  }

  @override
  void dispose() {
    // 清理资源
    _agent?.close();
    super.dispose();
  }

  Future<void> _connectToAgent() async {
    try {
      // 假设代理服务器地址为ws://localhost:8080
      await _agent?.connect('ws://localhost:8080');
      print("Connected to agent server");
    } catch (e) {
      print("Failed to connect to agent server: $e");
    }
  }

  Future<void> _sendMessage() async {
    if (_agent != null && _agent!.isConnected!) {
      String message = "Hello, Agent!";
      await _agent?.sendMessage(message);
      print("Sent message: $message");
    } else {
      print("Agent is not connected");
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Agent Dart Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            ElevatedButton(
              onPressed: _sendMessage,
              child: Text('Send Message'),
            ),
          ],
        ),
      ),
    );
  }
}

在这个示例中,我们做了以下几件事:

  1. pubspec.yaml文件中添加了agent_dart依赖。
  2. MyApp应用中创建了一个简单的用户界面,包含一个按钮。
  3. _MyHomePageState中初始化了Agent实例,并设置了消息接收和连接状态变化的回调。
  4. 实现了_connectToAgent方法来连接到代理服务器。
  5. 实现了_sendMessage方法来发送消息到代理服务器。

请注意,这个示例假设代理服务器已经在监听ws://localhost:8080。你需要根据你的实际情况调整连接地址和端口。此外,agent_dart插件的具体API和方法可能会随着版本更新而变化,请参考最新的官方文档以确保代码的准确性和兼容性。

回到顶部