netty系列之:选byte还是选message?这是一个问题

简介: netty系列之:选byte还是选message?这是一个问题

目录



简介


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!

相关文章
|
边缘计算 算法 安全
CDN百科第五讲 | CDN和游戏加速器有什么区别?
很多懂IT的游戏玩家都会将CDN和游戏加速器混淆,实际上从效果上看,CDN和网游加速器都具备让网络访问变快的能力,可以帮助玩家游戏的体验和访问效率提升,但是在它们在原理上是有本质区别的,本期CDN百科为你解答。
3371 0
CDN百科第五讲 | CDN和游戏加速器有什么区别?
flutter系列之:flutter中常用的GridView layout详解
GridView是一个网格化的布局,如果在填充的过程中子组件超出了展示的范围的时候,那么GridView会自动滚动。 因为这个滚动的特性,所以GridView是一个非常好用的Widget。今天我们一起来探索一下GridView这个layout组件的秘密。
flutter系列之:flutter中常用的GridView layout详解
|
XML Java 应用服务中间件
|
测试技术 Python
经典实践 | 网速测速小工具(上)
经典实践 | 网速测速小工具(上)
505 0
|
算法 计算机视觉
最新上线!MMTracking 视频实例分割食用指南
VIS 旨在检测、跟踪、分割视频里出现的物体,也就是在多目标跟踪任务的基础上更进一层,需要提供每个物体的 mask 信息。
612 0
最新上线!MMTracking 视频实例分割食用指南
|
存储 SQL 运维
Dataphin跨租户发布功能简介
Dataphin提供两种项目模式:Basic简单模式和生产开发隔离的Dev-Prod模式。使用开发生产隔离的模式,可以提供代码及数据的生产开发环境隔离。然而在某些对安全性要求更高的场景(比如金融场景),客户需要对生产和开发环境进行物理的隔离。Dataphin的3.2新版本提供的跨租户发布功能也是为了满足该需求而发布。本文将介绍跨租户发布的基本流程及功能介绍
Dataphin跨租户发布功能简介
|
存储 关系型数据库 MySQL
ARM+麒麟大数据环境搭建:MySQL8
ARM+麒麟大数据环境搭建:MySQL8
1744 0
ARM+麒麟大数据环境搭建:MySQL8
|
弹性计算
云平台分为三种类型IaaS, PaaS和SaaS
云平台分为三种类型IaaS, PaaS和SaaS
1587 0