首页 > 解决方案 > 一个 NettyServer 的 Avro RPC 多个响应程序

问题描述

我正在研究 Avro RPC,我正在尝试创建一个简单的示例来更好地理解它。

但我面临一个困难:我不能运行一个以上的服务器Responder,因为 NettyServer 构造函数只允许我使用一个:

public NettyServer(Responder responder, InetSocketAddress addr)

因此,如果我有多个 IDL,如下所示:

@namespace("foo.bar")
protocol FooProtocol {
    void foo();
}

@namespace("foo.bar")
protocol BarProtocol {
    void bar();
}

我无法将两者都添加到我的 NettyServer(如监听同一个端口):

object FooProtocolImpl : FooProtocol {

    override fun foo(): Void? {return null}
}
object BarProtocolImpl : BarProtocol {
    override fun bar(): Void? {return null}
}

val server = NettyServer(SpecificResponder(FooProtocol.PROTOCOL, FooProtocolImpl), InnetSocketAddress(9090))

如何将 BarProtocol 添加到我的服务器?如何使这个 NettyServer 对这两种协议都有用?

标签: kotlinnettyrpcavroidl

解决方案


Doug Cutting 在GrokBase的一篇文章指出:

当前每个协议都需要一个单独的响应程序。如果使用 HTTP,则可以配置不同的 ResponderServlet,以便在不同的 URL 上运行不同的协议。对于 NettyServer 和 SaslSocketServer,必须在不同的端口上运行不同的协议。

但是请注意,可以创建一个结合了其他几个协议的协议并提供服务。例如,使用 Java 反射,如果您有一个协议的 Java 接口 A 和另一个协议的 Java 接口 B,那么您可以实现“接口 C 扩展 A、B”并为该协议提供服务。然后,会说 A、B 或 C 的客户端可以连接。通过将各种客户端协议导入服务器协议,可以使用 Java 的特定编译器实现类似的效果。

http://avro.apache.org/docs/current/idl.html#imports

因此,另一种选择是创建一个protocol“实现”所有协议的方法,例如:

@namespace("foo.bar")
protocol AllProtocols {
    import idl "foo.avdl"
    import idl "bar.avdl"
}

并创建实现此协议的类:

object AllProtocolsImpl : AllProtocols {
    override fun foo(): Void? {return null}
    override fun bar(): Void? {return null}

}

然后创建服务于该协议的服务器:

val server = NettyServer(SpecificResponder(AllProtocols.PROTOCOL, AllProtocolsImpl), InetSocketAddress(9090))

任何需要 Foo 或 Bar 的客户端都可以连接到这个服务器并使用它的协议。


推荐阅读