Java NIO框架Netty教程(三)- 字符串消息收发

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

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

?
01
02
03
04
05
06
07
08
09
10
SendBuffer acquire(Object message) {
         if (message instanceof ChannelBuffer) {
             return acquire((ChannelBuffer) message);
         } else if (message instanceof FileRegion) {
             return acquire((FileRegion) message);
         }
 
         throw new IllegalArgumentException(
                 "unsupported message type: " + message.getClass());
     }

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

?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/**
  * @author lihzh
  * @alia OneCoder
  */
public class MessageServer {
 
     public static void main(String args[]) {
         // Server服务启动器
         ServerBootstrap bootstrap = new ServerBootstrap(
                 new NioServerSocketChannelFactory(
                         Executors.newCachedThreadPool(),
                         Executors.newCachedThreadPool()));
         // 设置一个处理客户端消息和各种消息事件的类(Handler)
         bootstrap.setPipelineFactory( new ChannelPipelineFactory() {
             @Override
             public ChannelPipeline getPipeline() throws Exception {
                 return Channels.pipeline( new MessageServerHandler());
             }
         });
         // 开放8000端口供客户端访问。
         bootstrap.bind( new InetSocketAddress( 8000 ));
     }
 
     private static class MessageServerHandler extends SimpleChannelHandler {
 
         /**
          * 用户接受客户端发来的消息,在有客户端消息到达时触发
          *
          * @author lihzh
          * @alia OneCoder
          */
         @Override
         public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
             ChannelBuffer buffer = (ChannelBuffer) e.getMessage();
             System.out.println(buffer.toString(Charset.defaultCharset()));
         }
 
     }
}
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/**
  * @author lihzh
  * @alia OneCoder
  */
public class MessageClient {
 
     public static void main(String args[]) {
         // Client服务启动器
         ClientBootstrap bootstrap = new ClientBootstrap(
                 new NioClientSocketChannelFactory(
                         Executors.newCachedThreadPool(),
                         Executors.newCachedThreadPool()));
         // 设置一个处理服务端消息和各种消息事件的类(Handler)
         bootstrap.setPipelineFactory( new ChannelPipelineFactory() {
             @Override
             public ChannelPipeline getPipeline() throws Exception {
                 return Channels.pipeline( new MessageClientHandler());
             }
         });
         // 连接到本地的8000端口的服务端
         bootstrap.connect( new InetSocketAddress( "127.0.0.1" , 8000 ));
     }
 
     private static class MessageClientHandler extends SimpleChannelHandler {
 
         /**
          * 当绑定到服务端的时候触发,给服务端发消息。
          *
          * @alia OneCoder
          * @author lihzh
          */
         @Override
         public void channelConnected(ChannelHandlerContext ctx,
                 ChannelStateEvent e) {
             // 将字符串,构造成ChannelBuffer,传递给服务端
             String msg = "Hello, I'm client." ;
             ChannelBuffer buffer = ChannelBuffers.buffer(msg.length());
             buffer.writeBytes(msg.getBytes());
             e.getChannel().write(buffer);
         }
     }
 
}

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值