当前位置: 首页 > 后端技术 > Java

netty系列:选择字节还是消息?这是一道题

时间:2023-04-01 17:24:00 Java

介绍UDT给了你两个选择,字节流或者消息,你应该选择哪个?经验告诉我们,只有小学生才会做选择题,我们应该都有!类型定义UDT的两种类型是如何定义的?查看com.barchart.udt包,可以发现TypeUDT枚举类中定义了这两种类型。STREAM(1),DATAGRAM(2),一种叫做STREAM,它的代码是1。一种叫做DATAGRAM,它的代码是2。我们可以根据两种不同的类型创建不同的selectorProvider和channelFactory。而这两个正是你构建netty服务所需要的。在NioUdtProvider工具类中,netty为我们提供了TypeUDT和KindUDTChannelFactory的六种组合,它们分别是:对于Stream:BYTE_ACCEPTOR、BYTE_CONNECTOR、BYTE_RENDEZVOUS。对于消息:MESSAGE_ACCEPTOR、MESSAGE_CONNECTOR和MESSAGE_RENDEZVOUS。同样,对应的SelectorProvider有两个,分别是:BYTE_PROVIDER和MESSAGE_PROVIDER。搭建UDT流服务器如果要搭建UDT流服务器,首先需要使用NioUdtProvider.BYTE_PROVIDER创建一个NioEventLoopGroup:finalNioEventLoopGroupacceptGroup=newNioEventLoopGroup(1,acceptFactoryNioUdtProvider.BYTE_PROVIDER);finalNioEventLoopGroupconnectGroup=newNioEventLoopGroup(1,connectFactory,NioUdtProvider.BYTE_PROVIDER);在这里,我们创建了两个事件循环,acceptLoop和connectLoop。接下来就是在ServerBootstrap中绑定以上两组,并指定channelFactory。这里我们需要NioUdtProvider.BYTE_ACCEPTOR:finalServerBootstrapboot=newServerBootstrap();boot.group(acceptGroup,connectGroup).channelFactory(NioUdtProvider.BYTE_ACCEPTOR).option(ChannelOption.SO_BACKLOG,10).handler(newLoggingvel.INFO)).childHandler(newChannelInitializer(){@OverridepublicvoidinitChannel(finalUdtChannelch){ch.pipeline().addLast(newLoggingHandler(LogLevel.INFO),newUDTByteEchoServerHandler());}});很简单。搭建UDT消息服务器搭建UDT消息服务器的步骤和stream很相似,不同的是需要使用NioUdtProvider.MESSAGE_PROVIDER作为selectorProvider:finalNioEventLoopGroupacceptGroup=newNioEventLoopGroup(1,acceptFactory,NioUdtProvider.MESSAGE_PROVIDER);finalNioEventLoopGroup1NioEventLoop=LoopGroup1,connectFactory,NioUdtProvider.MESSAGE_PROVIDER);然后在绑定ServerBootstrap的时候使用NioUdtProvider.MESSAGE_ACCEPTOR作为channelFactory:finalServerBootstrapboot=newServerBootstrap();boot.group(acceptGroup,connectGroup).channelFactory(NioUdtProvider.MESSAGE_ACCEPTOR).option(ChannelOption.SO_BACKLOG,10).handler(newLoggingHandler(LogLevel.INFO)).childHandler(newChannelInitializer(){@OverridepublicvoidinitChannel(finalUdtChannelch)抛出异常on{ch.pipeline().addLast(newLoggingHandler(LogLevel.INFO),newUDTMsgEchoServerHandler());}});这也很简单。Stream和Message的handler是不同的UDT类型,需要使用不同的handler。对于Stream来说,它的底层是byte,所以我们的消息处理也是byte的形式。我们通过以下方式构造消息:privatefinalByteBufmessage;message=Unpooled.buffer(UDTByteEchoClient.SIZE);消息.writeBytes("www.flydean.com".getBytes(StandardCharsets.UTF_8));然后使用ctx.writeAndFlush(message)将其写入通道。对于message,其实就是封装了ByteBuf格式。netty中有一个对应的类叫UdtMessage:publicfinalclassUdtMessageextendsDefaultByteBufHolderUdtMessage是一个ByteBufHolder,所以它实际上是对ByteBuf的一个封装。我们需要将ByteBuf封装到UdtMessage中:privatefinalUdtMessagemessage;finalByteBufbyteBuf=Unpooled.buffer(UDTMsgEchoClient.SIZE);byteBuf.writeBytes("www.flydean.com".getBytes(StandardCharsets.UTF_8));message=newUdtMessage(byteBuf);然后将此UdtMessage发送到通道:ctx.writeAndFlush(message);这样,您将学会使用UDT协议中的流和消息这两种数据类型。总结您可能认为不同的数据类型实现起来如此简单。这都要归功于netty出色的包装和设计。谢谢网络!本文示例可参考:learn-netty4本文已收录于http://www.flydean.com/40-netty-udt-support-2/最通俗的解读,最深刻的干货,最简洁的教程,许多你不为人知的小技巧等你来发现!欢迎关注我的公众号:《程序那些事儿》,懂技术,更懂你!