写点什么

netty 系列之: 真正的平等–UDT 中的 Rendezvous

作者:程序那些事
  • 2022 年 1 月 06 日
  • 本文字数:1928 字

    阅读完需:约 6 分钟

netty系列之:真正的平等–UDT中的Rendezvous

简介

在我们之前提到的所有 netty 知识中,netty 好像都被分为客户端和服务器端两部分。服务器端监听连接,并对连接中的消息进行处理。而客户端则向服务器端建立请求连接,从而可以发送消息。


但是这一切都要在 UDT 协议中被终结,因为 UDT 提供了 Rendezvous,一种平等的连接类型,节点之间是对等关系。


从来都没有救世主,也没有神仙和皇帝,只有同为节点的好兄弟。

建立支持 Rendezvous 的服务器

因为是对等的关系,所以这里不需要使用到 ServerBootstrap,使用普通的 Bootstrap 就够了。


group 还是要的,这里使用 NioEventLoopGroup,NioEventLoopGroup 需要提供了 SelectorProvider。UDT 提供了两种 provider,分别是 NioUdtProvider.BYTE_PROVIDER 和 NioUdtProvider.MESSAGE_PROVIDER,分别表示 stream 和 message 两种格式:


final NioEventLoopGroup connectGroup = new NioEventLoopGroup(1,                connectFactory, NioUdtProvider.BYTE_PROVIDER);
final NioEventLoopGroup connectGroup = new NioEventLoopGroup(1, connectFactory, NioUdtProvider.MESSAGE_PROVIDER);
复制代码


接下来就是创建 Bootstrap,并绑定 group 和设置 channelFactory.


当然,这里的 channelFactory 也有两种,分别是 NiNioUdtProvider.BYTE_RENDEZVOUS 和 NioUdtProvider.BYTE_RENDEZVOUS。


那么可以有下面两种创建的方法,第一种是 byte stream 的:


 final Bootstrap bootstrap = new Bootstrap();            bootstrap.group(connectGroup)                    .channelFactory(NioUdtProvider.BYTE_RENDEZVOUS)                    .handler(new ChannelInitializer<UdtChannel>() {                        @Override                        protected void initChannel(UdtChannel ch) throws Exception {                            ch.pipeline().addLast(                                    new LoggingHandler(LogLevel.INFO),                                    new UDTByteHandler(messageSize));
复制代码


第二种是 message 的:


final Bootstrap boot = new Bootstrap();            boot.group(connectGroup)                    .channelFactory(NioUdtProvider.MESSAGE_RENDEZVOUS)                    .handler(new ChannelInitializer<UdtChannel>() {                        @Override                        public void initChannel(final UdtChannel ch)                                throws Exception {                            ch.pipeline().addLast(                                    new LoggingHandler(LogLevel.INFO),                                    new UDTMsgHandler(messageSize));                        }                    });
复制代码


至此,两个支持不同 UDT 类型的 Rendezvous 服务器就建立起来了。


接下来就是对消息的处理了。

处理不同的消息

有了支持 byte 和 message 两种格式的服务器,接下来就是如何处理对应的消息了。


对于 byte 格式的 UDT,channel 中传输的消息就是 ByteBuf,我们只需要构建 ByteBuf 的消息,然后在 channel 中传输即可:


private final ByteBuf messagemessage = Unpooled.buffer(messageSize);message.writeBytes("www.flydean.com".getBytes(StandardCharsets.UTF_8));ctx.writeAndFlush(message);
复制代码


对应 message 格式的 UDT,netty 提供了一个专门的类 UdtMessage 对其进行封装,UdtMessage 继承值 DefaultByteBufHolder,他就是对 ByteBuf 的封装。


我们可以这样创建一个 UdtMessage 并发送它:


private final UdtMessage message;final ByteBuf byteBuf = Unpooled.buffer(messageSize);byteBuf.writeBytes("www.flydean.com".getBytes(StandardCharsets.UTF_8));message = new UdtMessage(byteBuf);
ctx.writeAndFlush(message);
复制代码

节点之间的交互

上面我们分别建立了两个节点,这两个节点是对等关系,那么怎么将这两个节点联系起来呢?


我们调用 Bootstrap 的 connect 方法如下:


final ChannelFuture f = boot.connect(peer, self).sync();            f.channel().closeFuture().sync();
复制代码


这里的 connect 传入两个 SocketAddress 参数,第一个参数是 remoteAddress,第二个参数表示的是 localAddress.


当然,connect 还有一种常用的用法就是连接到远程的服务器:


public ChannelFuture connect(String inetHost, int inetPort)
复制代码


这也是我们最常见的那种用法。

总结

以上就是 UDT 中的 Rendezvous 的使用。


本文的例子可以参考:learn-netty4


本文已收录于 http://www.flydean.com/41-netty-udt-byte-message/

最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!

欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!

发布于: 刚刚
用户头像

关注公众号:程序那些事,更多精彩等着你! 2020.06.07 加入

最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧,尽在公众号:程序那些事!

评论

发布
暂无评论
netty系列之:真正的平等–UDT中的Rendezvous