【问题标题】:Reading/writing Cap’n Proto messages partially部分读取/写入 Cap'n Proto 消息
【发布时间】:2017-10-11 14:32:30
【问题描述】:

我正在尝试在现有项目中使用 Cap'n Proto,该项目由通过 UDS 进行通信的客户端和服务器组成。我没有资源(我怀疑它会被接受)来重做所有客户端-服务器 RPC,但我想从 Cap'n Proto 序列化机制中受益。不幸的是,在我看来这是不可能的。

最大的问题是服务器端,它是单线程的(如果多线程没有任何严肃的论据,它将一直如此)并使用它自己的基于轮询的循环。所有事件都被部分读取,服务器无法阻止等待任何事件被完全读取 - 这就是我卡住的地方。我们有自己的协议和类来包装消息,当事件被完全读取时,它们可以消耗文件描述符中的字节并通知,以便服务器可以处理它。我想我已经分析了大部分 Cap'n Proto 接口(序列化、异步序列化),并且看起来,如果不进行任何修改,它就不能以相同的方式使用。

我真的希望我错过了什么。我有吗?

【问题讨论】:

    标签: c++ asynchronous capnproto


    【解决方案1】:

    有两种方法可以解决这个问题:

    • 困难:您可以尝试与 KJ 异步 I/O 框架(由 Cap'n Proto 使用)集成。 KJ 事件循环实际上可以与其他事件循环集成并在它们之上运行——但这很棘手。例如,node-capnp 包含将 KJ 事件循环与 libuv 集成的代码,如 this source file 的第一部分所示。一旦你有了必要的粘合剂,你就可以编写使用capnp/serialize-async.h 中的接口的 KJ 风格的异步代码。
    • 简单方法:您可以使用事件基础结构编写简单的代码,而不是尝试集成 KJ,该基础结构直接从文件描述符中读取数据,然后使用 capnp::expectedSizeInWordsFromPrefix()(来自 capnp/serialize.h)来确定是否它已经收到了整个消息。如果该函数返回的数字大于您已有的数字,那么您没有完整的消息,必须继续等待。获得完整消息后,您可以使用 capnp::FlatArrayMessageReader 对其进行解析。

    【讨论】:

    • 谢谢。我非常感谢代码作者,他在 Stack Overflow 上很活跃:)
    • expectSizeInWordsFromPrefix 是否也适用于打包邮件?我总是得到巨大的数字......
    • @hunyadym 不,它不适用于打包消息。为打包的消息实现这样的东西实际上是相当困难的。你最好明确地写一个长度前缀。 :/ 我为此提交了一个问题:github.com/capnproto/capnproto/issues/590
    • 有没有办法知道,通过套接字发送什么类型的消息?或者您能否建议先发送操作类型的最佳做法?
    • @zoska 我建议创建一个主消息,其中包含您想要支持的所有消息类型的union。然后,始终发送和接收主消息的实例。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多