我有一个多路复用应用程序协议,我已经实现了流水线阶段,用于在两个方向上处理代表协议中每种消息类型的Kotlin数据类。没有正式的请求-响应模式;客户端和服务器可以在套接字寿命的任何时候互相发送消息。
在协议中,存在一个约束,即对于任何连接的客户端,消息都是按顺序处理的。也就是说,当服务器从客户端接收到一条消息时,它无法处理来自客户端的下一条消息,直到前一条完全处理完为止。相同的规则适用于处理来自服务器的消息的客户端。这或多或少是如何在Netty中处理通道管道的。给定的管道阶段一次只能处理一件事。通过在新的执行程序组上使用阻塞管道阶段,可以轻松进行编码。
但是,我想为客户端可能以挂起函数的形式发送的每种消息编写处理程序,因为服务器响应客户端消息可能执行的操作范围非常广泛,并且可能涉及与其他人联系服务器或数据库,并且一组消息类型还可以在处理期间在内部锁定服务器状态的某些部分,以排除其他并发连接的客户端。因此,我需要一种从Channel管道的尾部过渡到协程上下文的方法,以使管道阶段被“阻止”继续处理消息,但在此阶段不阻止其他通道的管道的处理,并且无需为每个套接字创建单线程事件执行程序。
我曾经考虑过使用Netty的单独的调度程序和事件循环来表示每个客户端会话的处理,并使用actor来代表每个客户端会话,以便将接收到的消息发送到actor的邮箱通道,并且协程按顺序对其进行处理接收到,我可以取消该actor,并在取消它时关闭REPO_B
,反之亦然。但这很丑陋,而且不符合Netty的精神。
tl; dr我想知道,实现流水线阶段将其暂停函数与其执行者组完全集成的最佳方法是什么?
答案 0 :(得分:-1)
过去,我建立了一座连接Vert.x(基于Netty)和协同程序的桥梁。 https://paste.ubuntu.com/p/9VxZkdn9tt/ (注意:它有一些我尚未修复的错误。)
Vert.x提供回调样式ReadStream。我将其转换为协程中的块同步样式InputStream。像InputStream
中的java.io
。
因此,这不是避免问题的最佳方法。但是看起来,异步样式有时会出现一些问题。