4.2 传输API

传输API的核心是通道接口,该通道接口用于所有出站操作。

查看Channel接口的层次结构,如图4.1所示。

Figure 4.1 Channel interface hierarchy

您可以在图4.1中看到,通道分配有ChannelPipeline和ChannelConfig。

ChannelConfig具有为通道存储的整个配置设置,并允许即时更新它们。通常,传输具有特定的配置设置,这些设置仅在传输上可用,而在其他实现上则不可行。为此,它可以公开ChannelConfig的子类型。有关更多信息,请参考特定ChannelConfig实现的javadocs。

ChannelPipeline包含应用于通过通道传递的入站和出站数据的所有ChannelHandler实例。这些ChannelHandler实现使您可以对状态更改做出反应或转换数据。本书包括有关ChannelHandlers的详细内容的一章,因为它们是Netty的关键概念之一。

现在,我会注意到您可以将ChannelHandler用于以下任务:

  • 将数据从一种格式转换为另一种格式。

  • 通知您异常情况。

  • 在管道变为活动状态或不活动状态时通知您。

  • 从EventLoop注册/注销频道后通知您。

  • 通知您有关特定于用户的事件。

这些ChannelHandler实例放置在ChannelPipeline中,一个接一个地执行。它类似于一条链,如果您过去曾经在servlet中使用过它,您可能会很熟悉。有关ChannelHandler主题的更多详细信息,请参见第6章。

Channelpipeline

ChannelPipeline实现了拦截过滤器模式,这意味着您可以链接不同的ChannelHandlers并拦截通过ChannelPipeline的数据或事件。可以将它想像为UNIX管道,它允许链接不同的命令(这里的ChannelHandler将是命令)

您还可以即时修改ChannelPipeline,这使您可以在需要时添加/删除ChannelHandler实例。这可用于通过Netty构建高度灵活的应用程序。

除了访问分配的ChannelPipeline和ChannelConfig外,您还可以在Channel本身上进行操作。通道提供了许多方法,但是最重要的方法在表4.1中列出。

Method name

Description

eventLoop()

Returns the EventLoop that is assigned to the channel

pipeline()

Returns the ChannelPipeline that is assigned to the channel

isActive()

Returns if the channel is active, which means its connected to the remote peer

localAddress()

Returns the SocketAddress that is bound local

remoteAddress()

Returns the SocketAddress that is bound remote

write()

Writes data to the remote peer. This data is passed though the ChannelPipeline

稍后您将进一步了解如何使用所有这些功能。到目前为止,请始终记住,您将始终在相同的接口上进行操作,这为您提供了高度的灵活性,并在您尝试使用其他传输实现时避免进行大规模的重构。

要将数据写入远程对等方,请调用Channel.write(),如以下清单所示。

Listing 4.5 Writing to a channel

请注意,Channel是线程安全的,这意味着可以从不同的线程对其进行操作是安全的。它的所有方法都可以在多线程环境中安全使用。因此,安全地将对它的引用存储在应用程序中,并在有需要向远程对等方写入内容时使用它就可以使用,即使使用许多线程也是如此。以下清单显示了一个使用多个线程编写的简单示例。

Listing 4.6 Using the channel from many threads

另外,此方法保证消息的写入顺序与传递给write方法的顺序相同。有关所有方法的完整参考,请参考提供的API文档(javadocs)。

了解所使用的接口很重要,但是了解Netty已经附带了哪些不同的传输实现也很有帮助。很有可能已经为您提供了一切。在下一节中,我将研究提供了哪些实现以及它们的行为。

最后更新于

这有帮助吗?