Reading/writing Cap’n Proto 部分消息
Reading/writing Cap’n Proto messages partially
我正在尝试在现有项目中使用 Cap'n Proto,该项目由通过 UDS 进行通信的客户端和服务器组成。我没有资源(我怀疑它会被接受)来重做所有客户端-服务器 RPC,但我想从 Cap'n Proto 序列化机制中受益。不幸的是,在我看来这是不可能的。
最大的问题是服务器端,它是单线程的(如果没有任何关于多线程的严肃论据,它将一直如此)并使用它自己的基于轮询的循环。所有事件都是部分读取的,服务器不能阻止等待任何事件被完全读取——这就是我被困的地方。我们有自己的协议和 类 包装消息,它可以从文件描述符中消耗字节并在事件被完全读取时通知,以便服务器可以处理它。我想我已经分析了大部分 Cap'n Proto 接口(序列化、异步序列化),并且看起来,如果不进行任何修改,它就不能以相同的方式使用。
我真希望我错过了什么。我有吗?
有两种方法可以解决这个问题:
- 困难的方法: 您可以尝试与 KJ 异步 I/O 框架(由 Cap'n Proto 使用)集成。 KJ 事件循环实际上可以与其他事件循环集成,并在它们之上 运行 —— 但它很棘手。例如,node-capnp 包含将 KJ 事件循环与 libuv 集成的代码,如 this source file 的第一部分所示。一旦你有了必要的胶水,你就可以编写使用
capnp/serialize-async.h
. 中的接口的 KJ 风格的异步代码
- 简单方法: 您可以使用事件基础结构编写简单的代码,直接从文件描述符读取数据,然后使用
capnp::expectedSizeInWordsFromPrefix()
而不是尝试集成 KJ (from capnp/serialize.h
) 来确定它是否已经收到了整个消息。如果该函数 returns 大于您已有的数字,那么您没有收到完整的消息,必须继续等待。获得完整消息后,您可以使用 capnp::FlatArrayMessageReader
对其进行解析。
我正在尝试在现有项目中使用 Cap'n Proto,该项目由通过 UDS 进行通信的客户端和服务器组成。我没有资源(我怀疑它会被接受)来重做所有客户端-服务器 RPC,但我想从 Cap'n Proto 序列化机制中受益。不幸的是,在我看来这是不可能的。
最大的问题是服务器端,它是单线程的(如果没有任何关于多线程的严肃论据,它将一直如此)并使用它自己的基于轮询的循环。所有事件都是部分读取的,服务器不能阻止等待任何事件被完全读取——这就是我被困的地方。我们有自己的协议和 类 包装消息,它可以从文件描述符中消耗字节并在事件被完全读取时通知,以便服务器可以处理它。我想我已经分析了大部分 Cap'n Proto 接口(序列化、异步序列化),并且看起来,如果不进行任何修改,它就不能以相同的方式使用。
我真希望我错过了什么。我有吗?
有两种方法可以解决这个问题:
- 困难的方法: 您可以尝试与 KJ 异步 I/O 框架(由 Cap'n Proto 使用)集成。 KJ 事件循环实际上可以与其他事件循环集成,并在它们之上 运行 —— 但它很棘手。例如,node-capnp 包含将 KJ 事件循环与 libuv 集成的代码,如 this source file 的第一部分所示。一旦你有了必要的胶水,你就可以编写使用
capnp/serialize-async.h
. 中的接口的 KJ 风格的异步代码
- 简单方法: 您可以使用事件基础结构编写简单的代码,直接从文件描述符读取数据,然后使用
capnp::expectedSizeInWordsFromPrefix()
而不是尝试集成 KJ (fromcapnp/serialize.h
) 来确定它是否已经收到了整个消息。如果该函数 returns 大于您已有的数字,那么您没有收到完整的消息,必须继续等待。获得完整消息后,您可以使用capnp::FlatArrayMessageReader
对其进行解析。