64. netty系列之:请netty再爱UDT一次
简介
UDT是一个非常优秀的协议,可以提供在UDP协议基础上进行高速数据传输。但是可惜的是在netty 4.1.7中,UDT传输协议已经被标记为Deprecated了!
意味着在后面的netty版本中,你可能再也看不到UDT协议了.
优秀的协议怎么能够被埋没,让我们揭开UDT的面纱,展示其优秀的特性,让netty再爱UDT一次吧。
netty对UDT的支持
netty对UDT的支持体现在有一个专门的UDT包来处理UDT相关事情:package io.netty.channel.udt。
这个包里面主要定义了UDT的各种channel、channel配置、UDT消息和提供ChannelFactory和SelectorProvider的工具类NioUdtProvider.
搭建一个支持UDT的netty服务
按照netty的标准流程,现在是需要创建一个netty服务的时候了。
netty创建server服务无非就是创建EventLoop、创建ServerBootstrap、绑定EventLoop、指定channel类型就完了,非常的简单。
唯一不同的就是具体的childHandler,可能根据具体协议的不同使用不同的处理方式。
当然,如果不是NioSocketChannel,那么对应的ChannelFactory和SelectorProvider也会有所变化。
没关系,我们先看下如何创建支持UDT的netty服务:
final ThreadFactory acceptFactory = new DefaultThreadFactory("accept");
final ThreadFactory connectFactory = new DefaultThreadFactory("connect");
final NioEventLoopGroup acceptGroup = new NioEventLoopGroup(1, acceptFactory, NioUdtProvider.BYTE_PROVIDER);
final NioEventLoopGroup connectGroup = new NioEventLoopGroup(1, connectFactory, NioUdtProvider.BYTE_PROVIDER);
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 UDTEchoServerHandler());
}
});
// 开启服务
final ChannelFuture future = boot.bind(PORT).sync();
可以看到,UDT和普通netty socket服务不同的地方在于它的selector和channelFactory都是由NioUdtProvider来提供了。
NioUdtProvider是netty核心包中的内容,他提供了对UDT的有用封装,我们不需要要懂太多UDT内部的实现,就可以使用UDT协议,是不是很美妙。
异常来袭
如果有小伙伴兴冲冲的拿上面这段代码去尝试运行,那么很可惜你会得到异常,异常大概类似下面的情况:
包com.barchart.udt找不到!
什么?直接使用netty包中的类居然会报错?是可忍孰不可忍!
我们来仔细分析一下,这里只有一个新的类就是NioUdtProvider,打开NioUdtProvider的源码,在import一栏,我们赫然发现居然引用了不属于netty的包,就是这些包报错了:
import com.barchart.udt.SocketUDT;
import com.barchart.udt.TypeUDT;
import com.barchart.udt.nio.ChannelUDT;
import com.barchart.udt.nio.KindUDT;
import com.barchart.udt.nio.RendezvousChannelUDT;
import com.barchart.udt.nio.SelectorProviderUDT;
虽然很诡异,但是我们要想程序跑起来还是需要找出这些依赖包,经过本人的跋山涉水、翻山越岭终于功夫不负苦心人,下面的依赖包找到了:
<dependency>
<groupId>com.barchart.udt</groupId>
<artifactId>barchart-udt-core</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.barchart.udt</groupId>
<artifactId>barchart-udt-bundle</artifactId>
<version>2.3.0</version>
</dependency>
netty核心包居然要依赖与第三方库,这可能就是netty准备删除对UDT支持的原因吧。
TypeUDT和KindUDT
如果你去查看barchart中类的具体信息,就会发现这个包的作者有个癖好,喜欢把类后面带上一个UDT。
当你看到满屏的类都是以UDT结尾的时候,没错,它就是netty UDT依赖的包barchart本包了。