天天看点

netty系列之:在netty中使用protobuf协议

简介

定义protobuf

定义handler

设置channelpipeline

构建client和server端并运行

总结

netty中有很多适配不同协议的编码工具,对于流行的google出品的protobuf也不例外。netty为其提供了protobufdecoder和protobufencoder两个工具还有对应的frame detection,接下来我们会通过一个例子来详细讲解如何在netty中使用protobuf。

我们举个最简单的例子,首先定义一个需要在网络中进行传输的message,这里我们定义一个student对象,他有一个age和一个name属性,如下所示:

使用下面的命令,对其进行编译:

可以看到生成了3个文件,分别是student,studentorbuilder和studentwrapper。其中student和studentorbuilder是我们真正需要用到的对象。

在handler中,我们主要进行对消息进行处理,这里我们在clienthandler中进行消息的构建和发送,studentclienthandler继承simplechannelinboundhandler并重新channelactive方法, 在该方法中我们使用protobuf的语法,构建一个新的student实例,并给他设置好age和name两个属性。

然后使用ctx.write和ctx.flush方法将其发送到server端:

studentserverhandler也是继承simplechannelinboundhandler,并重写channelread0方法,当server端读取到student消息的时候,日志输出,并将其回写到channel中,供clienthandler读取:

当client读取到消息之后,直接日志输出,不再做进一步处理,到此,一轮client和server端的交互就完成了:

在上一节,不管是在studentclienthandler还是在studentserverhandler中,我们都假设channel中传递的对象就是student,而不是原始的bytebuf。这是怎么做到的呢?

这里我们需要使用到netty提供的frame detection,netty为protobuf协议专门提供了protobufdecoder和protobufencoder,用于对protobuf对象进行编码和解码。

但是这两个编码和解码器分别是messagetomessageencoder和messagetomessagedecoder,他们是消息到消息的编码和解码器,所以还需要和frame detection配合使用。

netty同样提供了和protobuf配合使用的frame detector,他们是protobufvarint32framedecoder和protobufvarint32lengthfieldprepender。

varint32指的是protobuf的编码格式,第一个字节使用的是可变的varint。

有了frame detector和编码解码器,我们只需要将其顺序加入channelpipeline即可。

在客户端,studentclientinitializer继承自channelinitializer,我们需要重写其initchannel方法:

在服务器端,同样studentserverinitializer也继承自channelinitializer,也需要重写其initchannel方法:

这样channelpipeline也设置完成了。

最后好做的就是构建client和server端并运行,这和普通的netty客户端和服务器端并没有什么区别:

构建studentclient:

构建studentserver:

运行可得:

可见student消息已经发送和接收成功了。

netty提供了很多和协议适配的工具类,这样我们就可以专注于业务逻辑,不需要考虑具体的编码转换的问题,非常好用。

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

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