netty 服务详解

1:一个写有netty案例的:http://blog.csdn.net/hangge110/article/details/51613988

https://blog.csdn.net/kdy527/article/details/78553873

 

 

1.DiscardServerHandler 继承自 ChannelInboundHandlerAdapter,这个类实现了 ChannelInboundHandler接口,ChannelInboundHandler 提供了许多事件处理的接口方法,然后你可以覆盖这些方法。现在仅仅只需要继承 ChannelInboundHandlerAdapter 类而不是你自己去实现接口方法。

2.这里我们覆盖了 chanelRead() 事件处理方法。每当从客户端收到新的数据时,这个方法会在收到消息时被调用,这个例子中,收到的消息的类型是 ByteBuf

3.为了实现 DISCARD 协议,处理器不得不忽略所有接受到的消息。ByteBuf 是一个引用计数对象,这个对象必须显示地调用 release() 方法来释放。请记住处理器的职责是释放所有传递到处理器的引用计数对象。通常,channelRead() 方法的实现就像下面的这段代码:

 

4.exceptionCaught() 事件处理方法是当出现 Throwable 对象才会被调用,即当 Netty 由于 IO 错误或者处理器在处理事件时抛出的异常时。在大部分情况下,捕获的异常应该被记录下来并且把关联的 channel 给关闭掉。然而这个方法的处理方式会在遇到不同异常的情况下有不同的实现,比如你可能想在关闭连接之前发送一个错误码的响应消息。

目前为止一切都还不错,我们已经实现了 DISCARD 服务器的一半功能,剩下的需要编写一个 main() 方法来启动服务端的 DiscardServerHandler。

 

 

 

1.NioEventLoopGroup 是用来处理I/O操作的多线程事件循环器,Netty 提供了许多不同的 EventLoopGroup 的实现用来处理不同的传输。在这个例子中我们实现了一个服务端的应用,因此会有2个 NioEventLoopGroup 会被使用。第一个经常被叫做‘boss’,用来接收进来的连接。第二个经常被叫做‘worker’,用来处理已经被接收的连接,一旦‘boss’接收到连接,就会把连接信息注册到‘worker’上。如何知道多少个线程已经被使用,如何映射到已经创建的 Channel上都需要依赖于 EventLoopGroup 的实现,并且可以通过构造函数来配置他们的关系。

2.ServerBootstrap 是一个启动 NIO 服务的辅助启动类。你可以在这个服务中直接使用 Channel,但是这会是一个复杂的处理过程,在很多情况下你并不需要这样做。

3.这里我们指定使用 NioServerSocketChannel 类来举例说明一个新的 Channel 如何接收进来的连接。

4.这里的事件处理类经常会被用来处理一个最近的已经接收的 Channel。ChannelInitializer 是一个特殊的处理类,他的目的是帮助使用者配置一个新的 Channel。也许你想通过增加一些处理类比如DiscardServerHandler 来配置一个新的 Channel 或者其对应的ChannelPipeline 来实现你的网络程序。当你的程序变的复杂时,可能你会增加更多的处理类到 pipline 上,然后提取这些匿名类到最顶层的类上。

5.你可以设置这里指定的 Channel 实现的配置参数。我们正在写一个TCP/IP 的服务端,因此我们被允许设置 socket 的参数选项比如tcpNoDelay 和 keepAlive。请参考 ChannelOption 和详细的 ChannelConfig 实现的接口文档以此可以对ChannelOption 的有一个大概的认识。

6.你关注过 option() 和 childOption() 吗?option() 是提供给NioServerSocketChannel 用来接收进来的连接。childOption() 是提供给由父管道 ServerChannel 接收到的连接,在这个例子中也是 NioServerSocketChannel。

7.我们继续,剩下的就是绑定端口然后启动服务。这里我们在机器上绑定了机器所有网卡上的 8080 端口。当然现在你可以多次调用 bind() 方法(基于不同绑定地址)。

恭喜!你已经熟练地完成了第一个基于 Netty 的服务端程序。

 

一: 一个简单的案例

1:添加pom依赖

 

  1. <dependency>  
  2.     <groupId>io.netty</groupId>  
  3.     <artifactId>netty-all</artifactId>  
  4.     <version>4.1.0.Final</version>  
  5. </dependency>  

2:SimpleServer(服务端)

 

  1. package com.yingjun.netty.server;  
  2.   
  3. import io.netty.bootstrap.ServerBootstrap;  
  4. import io.netty.channel.ChannelFuture;  
  5. import io.netty.channel.ChannelInitializer;  
  6. import io.netty.channel.ChannelOption;  
  7. import io.netty.channel.EventLoopGroup;  
  8. import io.netty.channel.nio.NioEventLoopGroup;  
  9. import io.netty.channel.socket.SocketChannel;  
  10. import io.netty.channel.socket.nio.NioServerSocketChannel;  
  11.   
  12. /** 
  13.  *  
  14.  * Netty中,通讯的双方建立连接后,会把数据按照ByteBuf的方式进行传输, 
  15.  * 例如http协议中,就是通过HttpRequestDecoder对ByteBuf数据流进行处理,转换成http的对象。 
  16.  *  
  17.  */  
  18. public class SimpleServer {  
  19.     private int port;  
  20.   
  21.     public SimpleServer(int port) {  
  22.         this.port = port;  
  23.     }  
  24.   
  25.     public void run() throws Exception {  
  26.         //EventLoopGroup是用来处理IO操作的多线程事件循环器  
  27.         //bossGroup 用来接收进来的连接  
  28.         EventLoopGroup bossGroup = new NioEventLoopGroup();   
  29.         //workerGroup 用来处理已经被接收的连接  
  30.         EventLoopGroup workerGroup = new NioEventLoopGroup();  
  31.         try {  
  32.             //启动 NIO 服务的辅助启动类  
  33.             ServerBootstrap b = new ServerBootstrap();   
  34.             b.group(bossGroup, workerGroup)  
  35.                 //配置 Channel  
  36.                 .channel(NioServerSocketChannel.class)  
  37.                 .childHandler(new ChannelInitializer<SocketChannel>() {   
  38.                         @Override  
  39.                         public void initChannel(SocketChannel ch) throws Exception {  
  40.                             // 注册handler    
  41.                             ch.pipeline().addLast(new SimpleServerHandler());  
  42.                         }  
  43.                     })  
  44.                 .option(ChannelOption.SO_BACKLOG, 128)   
  45.                 .childOption(ChannelOption.SO_KEEPALIVE, true);   
  46.   
  47.             // 绑定端口,开始接收进来的连接  
  48.             ChannelFuture f = b.bind(port).sync();  
  49.             // 等待服务器 socket 关闭 。  
  50.             f.channel().closeFuture().sync();  
  51.         } finally {  
  52.             workerGroup.shutdownGracefully();  
  53.             bossGroup.shutdownGracefully();  
  54.         }  
  55.     }  
  56.       
  57.     public static void main(String[] args) throws Exception {  
  58.         new SimpleServer(9999).run();  
  59.     }  
  60. }  

3:SimpleServerHandler(服务端请求处理Handler)

 

  1. package com.yingjun.netty.server;  
  2.   
  3. import io.netty.buffer.ByteBuf;  
  4. import io.netty.channel.ChannelHandlerContext;  
  5. import io.netty.channel.ChannelInboundHandlerAdapter;  
  6.   
  7. public class SimpleServerHandler extends ChannelInboundHandlerAdapter {  
  8.   
  9.     @Override  
  10.     public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {  
  11.         System.out.println("SimpleServerHandler.channelRead");  
  12.         ByteBuf result = (ByteBuf) msg;  
  13.         byte[] result1 = new byte[result.readableBytes()];  
  14.         // msg中存储的是ByteBuf类型的数据,把数据读取到byte[]中  
  15.         result.readBytes(result1);  
  16.         String resultStr = new String(result1);  
  17.         // 接收并打印客户端的信息  
  18.         System.out.println("Client said:" + resultStr);  
  19.         // 释放资源,这行很关键  
  20.         result.release();  
  21.   
  22.         // 向客户端发送消息  
  23.         String response = "hello client!";  
  24.         // 在当前场景下,发送的数据必须转换成ByteBuf数组  
  25.         ByteBuf encoded = ctx.alloc().buffer(4 * response.length());  
  26.         encoded.writeBytes(response.getBytes());  
  27.         ctx.write(encoded);  
  28.         ctx.flush();  
  29.     }  
  30.   
  31.     @Override  
  32.     public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {  
  33.         // 当出现异常就关闭连接  
  34.         cause.printStackTrace();  
  35.         ctx.close();  
  36.     }  
  37.   
  38.     @Override  
  39.     public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {  
  40.         ctx.flush();  
  41.     }  
  42.   
  43. }  

4:SimpleServer(客户端)

 

  1. package com.yingjun.netty.server;  
  2.   
  3. import io.netty.bootstrap.Bootstrap;  
  4. import io.netty.bootstrap.ServerBootstrap;  
  5. import io.netty.channel.ChannelFuture;  
  6. import io.netty.channel.ChannelInitializer;  
  7. import io.netty.channel.ChannelOption;  
  8. import io.netty.channel.EventLoopGroup;  
  9. import io.netty.channel.nio.NioEventLoopGroup;  
  10. import io.netty.channel.socket.SocketChannel;  
  11. import io.netty.channel.socket.nio.NioServerSocketChannel;  
  12. import io.netty.channel.socket.nio.NioSocketChannel;  
  13.   
  14. public class SimpleClient {  
  15.       
  16.     public void connect(String host, int port) throws Exception {  
  17.         EventLoopGroup workerGroup = new NioEventLoopGroup();  
  18.   
  19.         try {  
  20.             Bootstrap b = new Bootstrap();  
  21.             b.group(workerGroup);  
  22.             b.channel(NioSocketChannel.class);  
  23.             b.option(ChannelOption.SO_KEEPALIVE, true);  
  24.             b.handler(new ChannelInitializer<SocketChannel>() {  
  25.                 @Override  
  26.                 public void initChannel(SocketChannel ch) throws Exception {  
  27.                     ch.pipeline().addLast(new SimpleClientHandler());  
  28.                 }  
  29.             });  
  30.   
  31.             // Start the client.  
  32.             ChannelFuture f = b.connect(host, port).sync();  
  33.   
  34.             // Wait until the connection is closed.  
  35.             f.channel().closeFuture().sync();  
  36.         } finally {  
  37.             workerGroup.shutdownGracefully();  
  38.         }  
  39.     }  
  40.       
  41.     public static void main(String[] args) throws Exception {  
  42.         SimpleClient client=new SimpleClient();  
  43.         client.connect("127.0.0.1"9999);  
  44.     }  
  45.       
  46. }  

 

5:SimpleServerHandler(客户端请求处理Handler springmvc+mybatis+spring 整合 下载地址  

 

  1. package com.yingjun.netty.server;  
  2.   
  3. import io.netty.buffer.ByteBuf;  
  4. import io.netty.channel.ChannelHandlerContext;  
  5. import io.netty.channel.ChannelInboundHandlerAdapter;  
  6.   
  7. public class SimpleClientHandler extends ChannelInboundHandlerAdapter {  
  8.   
  9.     @Override  
  10.     public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {  
  11.         System.out.println("SimpleClientHandler.channelRead");    
  12.         ByteBuf result = (ByteBuf) msg;    
  13.         byte[] result1 = new byte[result.readableBytes()];    
  14.         result.readBytes(result1);    
  15.         System.out.println("Server said:" + new String(result1));    
  16.         result.release();    
  17.     }  
  18.   
  19.     @Override  
  20.     public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {  
  21.         // 当出现异常就关闭连接  
  22.         cause.printStackTrace();  
  23.         ctx.close();  
  24.     }  
  25.   
  26.       
  27.     // 连接成功后,向server发送消息    
  28.     @Override    
  29.     public void channelActive(ChannelHandlerContext ctx) throws Exception {    
  30.         String msg = "hello Server!";    
  31.         ByteBuf encoded = ctx.alloc().buffer(4 * msg.length());    
  32.         encoded.writeBytes(msg.getBytes());    
  33.         ctx.write(encoded);    
  34.         ctx.flush();    
  35.     }    

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值