4个版本

0.3.0 2024年6月25日
0.2.4 2024年6月24日
0.2.3 2024年6月24日
0.2.0 2024年6月24日

#269 in 过程宏

Download history 310/week @ 2024-06-22 14/week @ 2024-06-29 14/week @ 2024-07-06 1/week @ 2024-07-13

每月98次下载

AGPL-3.0

42KB
577

Eagle

稳定性

Eagle仍处于早期开发阶段。性能并不理想,界面可能发生变化,文档尚未最终完成。基本功能已完全实现并按预期工作。

什么是Eagle?

Eagle是一个库,允许您轻松构建一个RPC协议。它使用宏生成所需的通信代码,并使添加新功能变得简单快捷。Eagle专门与tokio一起使用,并使用serde进行数据格式化。

请注意,由于eagle是一个纯过程宏库,您必须手动将兼容版本的tokioserderon以及可选的log添加到您的依赖项中。

使用Eagle

eagle的设计方式是作为您“服务器”和“客户端”之间的共享依赖项使用。这两个都应该在workspace中。创建一个共享crate,这两个组件都应该依赖它,这个crate应该有eagle作为依赖。默认情况下,eagle使用TCP进行通信,但您可以在eagle上禁用默认功能并启用unix功能来使用Unix套接字。

在这个crate中,您可以定义您的协议为一个枚举

use eagle::Protocol;
use serde::{Serialize, Deserialize};

#[derive(Clone, Serialize, Deserialize)]
pub struct ExampleStruct {
    a: i32,
    b: i32
}

#[derive(Protocol)]
pub enum Example {
    Addition((i32, i32), i32),
    StructuredDataAlsoWorks(ExampleStruct, ()),
    SetState(i32, i32),
    GetState((), i32)
}

每个变体描述了客户端可以调用的一个功能,变体中的第一个字段表示客户端可以发送的参数,第二个字段表示返回值。在上面的例子中,addition函数将接受两个 [i32],并返回另一个 [i32]。通过这种方式传递的数据必须实现 Clone 以及 serde::Serializeserde::Deserialize

Protocol 宏将在你的共享crate中创建多个导出。你可以在客户端和服务器中通过名称导入它们。

一旦你的协议定义完成,你就可以在服务器上实现它。为此,你必须首先实现你的协议处理程序。处理程序必须实现 Clone 以及你的协议的 ServerHandler 特性。对于上面的例子

struct ExampleHandler {
    state: i32
}
impl ExampleServerHandler for ExampleHandler {
    async fn addition(&mut self, a: i32, b: i32) -> i32 {
        a + b
    }

    async fn get_state(&mut self) -> i32 {
        self.state
    }

    async fn set_state(&mut self, state: i32) -> i32 {
        self.state = state;
        self.state
    }
}

你的处理程序现在可以被服务器使用。你可以轻松地将服务器绑定到套接字,使用

use shared::ExampleServer;

let handler = ExampleHandler { state: 0 };
let server_task = ExampleServer::bind(handler, "127.0.0.1:1234").await;
// Or, if you're using the 'unix' feature...
let server_task = ExampleServer::bind(handler, "/tmp/sock").await;

注意,bind 是一个异步函数,它永远不会返回,你必须将它放在一个单独的任务中。一旦绑定,服务器将等待连接并开始响应查询。

在客户端,你需要做的只是使用你的协议的 Client 来连接,然后你可以开始发送请求。

use shared::ExampleClient;

let client = ExampleClient::connect("127.0.0.1:1234").await.unwrap();
assert_eq!(client.addition(5, 2), 7);

许可证

Eagle 在 AGPL (GNU Affero General Public License) 许可下授权。要了解更多信息,请阅读 LICENSE.md

依赖关系

~250–700KB
~17K SLoC