关于java:netty系列之选byte还是选message这是一个问题

31次阅读

共计 3109 个字符,预计需要花费 8 分钟才能阅读完成。

简介

UDT 给了你两种抉择,byte stream 或者 message, 到底选哪一种呢?教训通知咱们,只有小学生才做选择题,而咱们应该全都要!

类型的定义

UDT 的两种类型是怎么定义的呢?

翻看 com.barchart.udt 包,能够发现这两种类型定义在 TypeUDT 枚举类中。

    STREAM(1),
    DATAGRAM(2), 

一个叫做 STREAM,它的 code 是 1。一个叫做 DATAGRAM,他的 code 是 2.

依据两个不同的类型咱们能够创立不同的 selectorProvider 和 channelFactory。而这两个正是构建 netty 服务所须要的。

在 NioUdtProvider 这个工具类中,netty 为咱们提供了 TypeUDT 和 KindUDT 的六种组合 ChannelFactory,他们别离是:

用于 Stream 的:BYTE_ACCEPTOR,BYTE_CONNECTOR,BYTE_RENDEZVOUS。

和用于 Message 的:MESSAGE_ACCEPTOR,MESSAGE_CONNECTOR 和 MESSAGE_RENDEZVOUS。

同样的,还有两个对应的 SelectorProvider, 别离是:

BYTE_PROVIDER 和 MESSAGE_PROVIDER.

搭建 UDT stream 服务器

如果要搭建 UDT stream 服务器,首先须要应用 NioUdtProvider.BYTE_PROVIDER 来创立 NioEventLoopGroup:

        final NioEventLoopGroup acceptGroup = new NioEventLoopGroup(1, acceptFactory, NioUdtProvider.BYTE_PROVIDER);
        final NioEventLoopGroup connectGroup = new NioEventLoopGroup(1, connectFactory, NioUdtProvider.BYTE_PROVIDER);

这里,咱们创立两个 eventLoop,别离是 acceptLoop 和 connectLoop。

接下来就是在 ServerBootstrap 中绑定下面的两个 group,并且指定 channelFactory。这里咱们须要 NioUdtProvider.BYTE_ACCEPTOR:

final ServerBootstrap boot = new ServerBootstrap();
            boot.group(acceptGroup, connectGroup)
                    .channelFactory(NioUdtProvider.BYTE_ACCEPTOR)
                    .option(ChannelOption.SO_BACKLOG, 10)
                    .handler(new LoggingHandler(LogLevel.INFO))
                    .childHandler(new ChannelInitializer<UdtChannel>() {
                        @Override
                        public void initChannel(final UdtChannel ch) {ch.pipeline().addLast(new LoggingHandler(LogLevel.INFO),
                                    new UDTByteEchoServerHandler());
                        }
                    });

就这么简略。

搭建 UDT message 服务器

搭建 UDT message 服务器的步骤和 stream 很相似,不同的是须要应用 NioUdtProvider.MESSAGE_PROVIDER 作为 selectorProvider:

        final NioEventLoopGroup acceptGroup =
                new NioEventLoopGroup(1, acceptFactory, NioUdtProvider.MESSAGE_PROVIDER);
        final NioEventLoopGroup connectGroup =
                new NioEventLoopGroup(1, connectFactory, NioUdtProvider.MESSAGE_PROVIDER);

而后在绑定 ServerBootstrap 的时候应用 NioUdtProvider.MESSAGE_ACCEPTOR 作为 channelFactory:

final ServerBootstrap boot = new ServerBootstrap();
            boot.group(acceptGroup, connectGroup)
                    .channelFactory(NioUdtProvider.MESSAGE_ACCEPTOR)
                    .option(ChannelOption.SO_BACKLOG, 10)
                    .handler(new LoggingHandler(LogLevel.INFO))
                    .childHandler(new ChannelInitializer<UdtChannel>() {
                        @Override
                        public void initChannel(final UdtChannel ch)
                                throws Exception {ch.pipeline().addLast(new LoggingHandler(LogLevel.INFO),
                                    new UDTMsgEchoServerHandler());
                        }
                    });

同样很简略。

Stream 和 Message 的 handler

不同的 UDT 类型,须要应用不同的 handler。

对于 Stream 来说,它的底层是 byte, 所以咱们的音讯解决也是以 byte 的模式进行的, 咱们以上面的形式来构建 message:

private final ByteBuf message;
message = Unpooled.buffer(UDTByteEchoClient.SIZE);
        message.writeBytes("www.flydean.com".getBytes(StandardCharsets.UTF_8));

而后应用 ctx.writeAndFlush(message) 将其写入到 channel 中。

对于 message 来说,它实际上格局对 ByteBuf 的封装。netty 中有个对应的类叫做 UdtMessage:

public final class UdtMessage extends DefaultByteBufHolder

UdtMessage 是一个 ByteBufHolder,所以它实际上是一个 ByteBuf 的封装。

咱们须要将 ByteBuf 封装成 UdtMessage:

private final UdtMessage message;
final ByteBuf byteBuf = Unpooled.buffer(UDTMsgEchoClient.SIZE);
        byteBuf.writeBytes("www.flydean.com".getBytes(StandardCharsets.UTF_8));
        message = new UdtMessage(byteBuf);

而后将这个 UdtMessage 发送到 channel 中:

ctx.writeAndFlush(message);

这样你就学会了在 UDT 协定中应用 stream 和 message 两种数据类型了。

总结

大家可能感觉不同的数据类型原来实现起来这么简略。这全都要归功于 netty 优良的封装和设计。

感激 netty!

本文的例子能够参考:learn-netty4

本文已收录于 http://www.flydean.com/40-netty-udt-support-2/

最艰深的解读,最粗浅的干货,最简洁的教程,泛滥你不晓得的小技巧等你来发现!

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

正文完
 0