博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java NIO框架Netty教程(三) 字符串消息收发(转)
阅读量:6293 次
发布时间:2019-06-22

本文共 2986 字,大约阅读时间需要 9 分钟。

hot3.png

了解了Netty的基本概念(),开发起来应该会顺手很多。 在“Hello World()”代码中,我们只是在完成绑定的时候,在各自的本地打印了简单的信息,并没有客户端和服务端的消息传递。这个肯定是最基本的功能。在上代码之前,先补充一个Netty中重要的概念,ChannelBuffer.

ChannelBuffer

 

 

Netty中的消息传递,都必须以字节的形式,以ChannelBuffer为载体传递。简单的说,就是你想直接写个字符串过去,对不起,抛异常。虽然,Netty定义的writer的接口参数是Object的,这可能也是会给新上手的朋友容易造成误会的地方。Netty源码中,是这样判断的:

Java代码   
  1.   SendBuffer acquire(Object message) {  
  2.   
  3. if (message instanceof ChannelBuffer) {  
  4.   
  5. return acquire((ChannelBuffer) message);  
  6.   
  7. else if (message instanceof FileRegion) {  
  8.   
  9. return acquire((FileRegion) message);  
  10.   
  11. }  
  12.   
  13.    
  14.   
  15. throw new IllegalArgumentException(  
  16.   
  17. "unsupported message type: " + message.getClass());  
  18.   
  19. }  

 所以,我们要想传递字符串,那么就必须转换成ChannelBuffer。明确了这一点,接下来我们上代码:

 

Java代码   
  1. /** 
  2.  
  3. * @author lihzh 
  4.  
  5. * @alia OneCoder 
  6.  
  7. * @blog http://www.coderli.com 
  8.  
  9. */  
  10.   
  11. public class MessageServer {  
  12.   
  13.    
  14.   
  15. public static void main(String args[]) {  
  16.   
  17. // Server服务启动器  
  18.   
  19. ServerBootstrap bootstrap = new ServerBootstrap(  
  20.   
  21. new NioServerSocketChannelFactory(  
  22.   
  23. Executors.newCachedThreadPool(),  
  24.   
  25. Executors.newCachedThreadPool()));  
  26.   
  27. // 设置一个处理客户端消息和各种消息事件的类(Handler)  
  28.   
  29. bootstrap.setPipelineFactory(new ChannelPipelineFactory() {  
  30.   
  31. @Override  
  32.   
  33. public ChannelPipeline getPipeline() throws Exception {  
  34.   
  35. return Channels.pipeline(new MessageServerHandler());  
  36.   
  37. }  
  38.   
  39. });  
  40.   
  41. // 开放8000端口供客户端访问。  
  42.   
  43. bootstrap.bind(new InetSocketAddress(8000));  
  44.   
  45. }  
  46.   
  47.    
  48.   
  49. private static class MessageServerHandler extends SimpleChannelHandler {  
  50.   
  51.    
  52.   
  53. /** 
  54.  
  55. * 用户接受客户端发来的消息,在有客户端消息到达时触发 
  56.  
  57. * 
  58.  
  59. * @author lihzh 
  60.  
  61. * @alia OneCoder 
  62.  
  63. */  
  64.   
  65. @Override  
  66.   
  67. public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {  
  68.   
  69. ChannelBuffer buffer = (ChannelBuffer) e.getMessage();  
  70.   
  71. System.out.println(buffer.toString(Charset.defaultCharset()));  
  72.   
  73. }  
  74.   
  75.    
  76.   
  77. }  
  78.   
  79. }  
  80.   
  81. /** 
  82.  
  83. * @author lihzh 
  84.  
  85. * @alia OneCoder 
  86.  
  87. * @blog http://www.coderli.com 
  88.  
  89. */  
  90.   
  91. public class MessageClient {  
  92.   
  93.    
  94.   
  95. public static void main(String args[]) {  
  96.   
  97. // Client服务启动器  
  98.   
  99. ClientBootstrap bootstrap = new ClientBootstrap(  
  100.   
  101. new NioClientSocketChannelFactory(  
  102.   
  103. Executors.newCachedThreadPool(),  
  104.   
  105. Executors.newCachedThreadPool()));  
  106.   
  107. // 设置一个处理服务端消息和各种消息事件的类(Handler)  
  108.   
  109. bootstrap.setPipelineFactory(new ChannelPipelineFactory() {  
  110.   
  111. @Override  
  112.   
  113. public ChannelPipeline getPipeline() throws Exception {  
  114.   
  115. return Channels.pipeline(new MessageClientHandler());  
  116.   
  117. }  
  118.   
  119. });  
  120.   
  121. // 连接到本地的8000端口的服务端  
  122.   
  123. bootstrap.connect(new InetSocketAddress("127.0.0.1"8000));  
  124.   
  125. }  
  126.   
  127.    
  128.   
  129. private static class MessageClientHandler extends SimpleChannelHandler {  
  130.   
  131.    
  132.   
  133. /** 
  134.  
  135. * 当绑定到服务端的时候触发,给服务端发消息。 
  136.  
  137. * 
  138.  
  139. * @alia OneCoder 
  140.  
  141. * @author lihzh 
  142.  
  143. */  
  144.   
  145. @Override  
  146.   
  147. public void channelConnected(ChannelHandlerContext ctx,  
  148.   
  149. ChannelStateEvent e) {  
  150.   
  151. // 将字符串,构造成ChannelBuffer,传递给服务端  
  152.   
  153. String msg = "Hello, I'm client.";  
  154.   
  155. ChannelBuffer buffer = ChannelBuffers.buffer(msg.length());  
  156.   
  157. buffer.writeBytes(msg.getBytes());  
  158.   
  159. e.getChannel().write(buffer);  
  160.   
  161. }  
  162.   
  163. }  
  164.   
  165.    
  166.   
  167. }  

 

与 “Hello World()” 样例代码不同的是,客户端在channel连通后,不是在本地打印,而是将消息转换成ChannelBuffer传递给服务端,服务端接受到ChannelBuffer后,解码成字符串打印出来。

同时,通过对比可以发现,变动的只是Handler里的代码,启动服务和绑定服务的代码没有变化,也就是我们在概念介绍里提到了,关注Handler,在Handler里处理我们自己的业务。所以,以后我们会只给出业务中关键代码,不会在上重复的代码:)
由于在Netty中消息的收发全依赖于ChannelBuffer,所以,下一章我们将会详细的介绍ChannelBuffer的使用。我们一起学习。

转载于:https://my.oschina.net/yearnfar/blog/151997

你可能感兴趣的文章
《Node.js入门经典》一2.3 安装模块
查看>>
《Java 开发从入门到精通》—— 2.5 技术解惑
查看>>
Linux 性能诊断 perf使用指南
查看>>
实操分享:看看小白我如何第一次搭建阿里云windows服务器(Tomcat+Mysql)
查看>>
Sphinx 配置文件说明
查看>>
数据结构实践——顺序表应用
查看>>
python2.7 之centos7 安装 pip, Scrapy
查看>>
机智云开源框架初始化顺序
查看>>
Spark修炼之道(进阶篇)——Spark入门到精通:第五节 Spark编程模型(二)
查看>>
一线架构师实践指南:云时代下双活零切换的七大关键点
查看>>
ART世界探险(19) - 优化编译器的编译流程
查看>>
玩转Edas应用部署
查看>>
music-音符与常用记号
查看>>
sql操作命令
查看>>
zip 数据压缩
查看>>
Python爬虫学习系列教程
查看>>
【数据库优化专题】MySQL视图优化(二)
查看>>
【转载】每个程序员都应该学习使用Python或Ruby
查看>>
PHP高级编程之守护进程,实现优雅重启
查看>>
PHP字符编码转换类3
查看>>