Netty学习之hello world


声明:本文转载自https://my.oschina.net/u/3475359/blog/1619607,转载目的在于传递更多信息,仅供学习交流之用。如有侵权行为,请联系我,我会及时删除。

(一) 说明:

​ 这是一个使用netty框架的demo,客户端发送一个消息到服务端,服务端将消息原样发送到客户端。

(二) 服务端:

(1) netty服务器端的ChannelHandler业务核心处理逻辑

​ 服务器端的处理器Handler命名为HelloWorldChannelHandler,继承自ChannelInboundHandlerAdapter适配器,有如下重载方法:

输入图片说明

我们只实现它的读取方法channelRead和异常处理方法exceptionCaught。

/**  * 业务核心处理逻辑  * @author comeCY  *  */ public class HelloWorldServerHandler extends ChannelInboundHandlerAdapter{            /**      * 读取的方法      * 覆盖channelRead方法处理所有接收到的数据      */     @Override       public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {           System.out.println("server channelRead..");           //服务端读取         System.out.println(ctx.channel().remoteAddress()+"->Server :"+ msg.toString());           //服务端转发         ctx.write("server write :"+msg);           ctx.flush();  //冲刷     }             /**      * 异常处理      */     @Override       public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {           cause.printStackTrace();  //打印异常堆栈跟踪         ctx.close();  //关闭通道     }   } 

(2) 引导服务器

  • 创建 ServerBootstrap 实例来引导服务器并随后绑定
  • 创建并分配一个 NioEventLoopGroup 实例来处理事件的处理,如接受新的连接和读/写数据。
  • 指定本地 InetSocketAddress 给服务器绑定
  • 通过 EchoServerHandler 实例给每一个新的 Channel 初始化
  • 最后调用 ServerBootstrap.bind() 绑定服务器
public class HelloWorldServer {   	       private int port;              public HelloWorldServer(int port) {           this.port = port;       }              public void start() throws Exception{           EventLoopGroup bossGroup = new NioEventLoopGroup(1);  //创建EventLoopGroup         EventLoopGroup workerGroup = new NioEventLoopGroup();           try {               ServerBootstrap sbs = new ServerBootstrap()                 	.group(bossGroup,workerGroup)  //创建ServerBootstrap                 .channel(NioServerSocketChannel.class)  //指定使用 NIO 的传输 Channel                 .localAddress(new InetSocketAddress(port))  //设置 socket 地址使用所选的端口                 .childHandler(new ChannelInitializer<SocketChannel>() {                             //添加 到 Channel 的 ChannelPipeline                         protected void initChannel(SocketChannel ch) throws Exception {                             //添加字符串编码和解码器                             ch.pipeline().addLast("decoder", new StringDecoder());                               ch.pipeline().addLast("encoder", new StringEncoder());                             //添加 HelloWorldSrverHandler                             ch.pipeline().addLast(new HelloWorldServerHandler());                           };                                                  }).option(ChannelOption.SO_BACKLOG, 128)                          .childOption(ChannelOption.SO_KEEPALIVE, true);  //启用心跳保活机制              // 绑定端口,开始接收进来的连接                ChannelFuture future = sbs.bind(port).sync();                                  System.out.println("Server start listen at " + port );                future.channel().closeFuture().sync();  //关闭 channel 和 块,直到它被关闭         } finally {         	bossGroup.shutdownGracefully();  //关闭 EventLoopGroup,释放所有资源             workerGroup.shutdownGracefully();         }       }                 public static void main(String[] args) throws Exception {           int port;           if (args.length > 0) {               port = Integer.parseInt(args[0]);           } else {               port = 8080;           }           new HelloWorldServer(port).start();  //呼叫服务器的start方法     }   }  

(三) 客户端:

(1) 客户端Handler

HelloWorldClientHandler也是继承自ChannelInboundHandlerAdapter,实现方法channelActive,channelRead,exceptionCaught与服务端类似。

public class HelloWorldClientHandler extends ChannelInboundHandlerAdapter{            @Override       public void channelActive(ChannelHandlerContext ctx) {         //当被通知该 channel 是活动的时候打印         System.out.println("HelloWorldClientHandler Active");       }          @Override       public void channelRead(ChannelHandlerContext ctx, Object msg) {         //记录接收到的消息        System.out.println("HelloWorldClientHandler read Message:"+msg);       }         @Override      public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {          cause.printStackTrace();  //记录日志错误并关闭 channel        ctx.close();       }   }  

(2) 引导客户端

  • Bootstrap 被创建来初始化客户端
  • NioEventLoopGroup 实例被分配给处理该事件的处理,这包括创建新的连接和处理 入站和出站数据
  • InetSocketAddress 为连接到服务器而创建
  • HelloWorldClientHandler 将被安装在 pipeline 当连接完成时
  • Bootstrap.connect()被调用连接到远程的服务器
public class HelloWorldClient {   	 	static final String HOST = System.getProperty("host", "127.0.0.1"); 	static final int PORT = Integer.parseInt(System.getProperty("port", "8080"));    	public static void main(String[] args) throws Exception { 		EventLoopGroup group = new NioEventLoopGroup(); 		 		try { 			Bootstrap b = new Bootstrap();  //创建 Bootstrap           /* 指定 EventLoopGroup 来处理客户端事件。由于我们使用 NIO 传输,所以用到了 NioEventLoopGroup 的实现*/ 			b.group(group)   			    .channel(NioSocketChannel.class)  //使用的 channel 类型是一个用于 NIO 传输 			    .option(ChannelOption.TCP_NODELAY, true)  //关闭Nagle算法,实时发送数据 			    .handler(new ChannelInitializer<SocketChannel>() {  				@Override 				protected void initChannel(SocketChannel ch) throws Exception { 					// TODO Auto-generated method stub 					ChannelPipeline p = ch.pipeline(); 					p.addLast("decoder", new StringDecoder());                       p.addLast("encoder", new StringEncoder()); 					p.addLast(new HelloWorldClientHandler()); 				} 			}); 			 			ChannelFuture future = b.connect(HOST, PORT).sync();  //连接到远程;等待连接完成 			//客户端写入 			future.channel().writeAndFlush("Hello Netty Server, I am a common client..."); 			future.channel().closeFuture().sync();  //阻塞直到 Channel 关闭 		} finally { 			group.shutdownGracefully();  //调用 shutdownGracefully() 来关闭线程池和释放所有资源 		} 	} }  	 

(四) 运行效果:

(1) 服务端

输入图片说明

(2) 客户端

输入图片说明

(五) 结语

学习博客:

参考书籍:

  • netty in action

本文发表于2018年02月07日 18:31
(c)注:本文转载自https://my.oschina.net/u/3475359/blog/1619607,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如有侵权行为,请联系我们,我们会及时删除.

阅读 1958 讨论 0 喜欢 0

抢先体验

扫码体验
趣味小程序
文字表情生成器

闪念胶囊

你要过得好哇,这样我才能恨你啊,你要是过得不好,我都不知道该恨你还是拥抱你啊。

直抵黄龙府,与诸君痛饮尔。

那时陪伴我的人啊,你们如今在何方。

不出意外的话,我们再也不会见了,祝你前程似锦。

这世界真好,吃野东西也要留出这条命来看看

快捷链接
网站地图
提交友链
Copyright © 2016 - 2021 Cion.
All Rights Reserved.
京ICP备2021004668号-1