简介

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/

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

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

netty系列之:选byte还是选message?这是一个问题的更多相关文章

  1. netty系列之:小白福利!手把手教你做一个简单的代理服务器

    目录 简介 代理和反向代理 netty实现代理的原理 实战 总结 简介 爱因斯坦说过:所有的伟大,都产生于简单的细节中.netty为我们提供了如此强大的eventloop.channel通过对这些简单 ...

  2. netty系列之:自定义编码和解码器要注意的问题

    目录 简介 自定义编码器和解码器的实现 ReplayingDecoder 总结 简介 在之前的系列文章中,我们提到了netty中的channel只接受ByteBuf类型的对象,如果不是ByteBuf对 ...

  3. Netty系列(四)TCP拆包和粘包

    Netty系列(四)TCP拆包和粘包 一.拆包和粘包问题 (1) 一个小的Socket Buffer问题 在基于流的传输里比如 TCP/IP,接收到的数据会先被存储到一个 socket 接收缓冲里.不 ...

  4. Netty 系列(三)Netty 入门

    Netty 系列(三)Netty 入门 Netty 是一个提供异步事件驱动的网络应用框架,用以快速开发高性能.高可靠性的网络服务器和客户端程序.更多请参考:Netty Github 和 Netty中文 ...

  5. 3. 彤哥说netty系列之Java BIO NIO AIO进化史

    你好,我是彤哥,本篇是netty系列的第三篇. 欢迎来我的公从号彤哥读源码系统地学习源码&架构的知识. 简介 上一章我们介绍了IO的五种模型,实际上Java只支持其中的三种,即BIO/NIO/ ...

  6. 4. 彤哥说netty系列之Java NIO实现群聊(自己跟自己聊上瘾了)

    你好,我是彤哥,本篇是netty系列的第四篇. 欢迎来我的公从号彤哥读源码系统地学习源码&架构的知识. 简介 上一章我们一起学习了Java中的BIO/NIO/AIO的故事,本章将带着大家一起使 ...

  7. 5. 彤哥说netty系列之Java NIO核心组件之Channel

    你好,我是彤哥,本篇是netty系列的第五篇. 简介 上一章我们一起学习了如何使用Java原生NIO实现群聊系统,这章我们一起来看看Java NIO的核心组件之一--Channel. 思维转变 首先, ...

  8. 6. 彤哥说netty系列之Java NIO核心组件之Buffer

    --日拱一卒,不期而至! 你好,我是彤哥,本篇是netty系列的第六篇. 简介 上一章我们一起学习了Java NIO的核心组件Channel,它可以看作是实体与实体之间的连接,而且需要与Buffer交 ...

  9. 7. 彤哥说netty系列之Java NIO核心组件之Selector

    --日拱一卒,不期而至! 你好,我是彤哥,本篇是netty系列的第七篇. 简介 上一章我们一起学习了Java NIO的核心组件Buffer,它通常跟Channel一起使用,但是它们在网络IO中又该如何 ...

随机推荐

  1. 响应式网页设计(Bootstrap)

    Bootstrap官网 AOS官网 Chrome官方教程 Chrome教程 Bootstrap官网中有许多Bootstrap网站示例,大家可以参考

  2. Augmentation For GAN

    目录 概 主要内容 Differentiable Augmentation Adaptive Augmentation 代码 Zhao S., Liu Z., Lin J., Zhu J. and H ...

  3. Momentum and NAG

    目录 Momentum Nesterov accelerated gradient NESTEROV 的另外一个方法? Momentum Momentum的迭代公式为: \[v_t = \gamma ...

  4. Insights直播回顾——手语服务,助力沟通无障碍

    HMS Core Insights第九期直播–手语服务,助力沟通无障碍,已于12月29日圆满结束,本期直播与小伙伴们一同了解了HMS Core手语服务的亮点特性.底层技术以及演进规划,下面我们一起来回 ...

  5. RTD2172方案|TYPEC转HDMI2.0转换器芯片|CS5265替代RTD2172

    RTD2172 USB Type-C到HDMI转换器结合了USB Type-C输入接口和数字高清多媒体接口(HDMI)输出.嵌入式微控制器(MCU)基于工业标准8051内核.接收器端口将信道配置(CC ...

  6. DP转LVDS方案 瑞奇达CS5211替代PS8625方案 CS5211芯片

    PS8625将作为DP或eDP接收器设备出现在视频源中,并将作为LVDS显示面板的LVDS源设备.该设备是一个完全集成的解决方案,不需要外部CPU.内存.时钟基准或电压调节器.PS8625可配置为从显 ...

  7. 编写Java程序,通过给定可变参数方法,计算任意给定的多个int类型数据之和

    返回本章节 返回作业目录 需求说明: 通过给定可变参数方法,计算任意给定的多个int类型数据之和. 实现思路: 定义可变形参方法,参数类型是int类型. 定义变量 sum 接受最终的和. 通过 for ...

  8. .net core的Swagger接口文档使用教程(一):Swashbuckle

    现在的开发大部分都是前后端分离的模式了,后端提供接口,前端调用接口.后端提供了接口,需要对接口进行测试,之前都是使用浏览器开发者工具,或者写单元测试,再或者直接使用Postman,但是现在这些都已经o ...

  9. Pytest_配置文件-pytest.ini(4)

    pytest配置文件可以改变pytest的默认运行方式,它是一个固定的文件名称pytest.ini. 存放路径为项目的根目录 解决中文报错 在讲解配置文件的可用参数前,我们先解决一个高概率会遇到的问题 ...

  10. JSch Algorithm negotiation fail

    https://stackoverflow.com/questions/30846076/jsch-algorithm-negotiation-fail As you can see, the ser ...