netty基本用法

1.客户端

①HelloClient.java

public class HelloClient {
	public static String host = "127.0.0.1";
	     public static int port = 7878;

	     /**
	      * @param args
	      * @throws InterruptedException
	      * @throws IOException
	      */
	     public static void main(String[] args) throws InterruptedException, IOException {
	         EventLoopGroup workGroup = new NioEventLoopGroup();
	         try {
	             Bootstrap b = new Bootstrap();
	             b.group(workGroup)
	             .channel(NioSocketChannel.class)
	             .handler(new HelloClientInitializer());

	             // 连接服务端
	             ChannelFuture future = b.connect(host, port).sync();

	             // 控制台输入
	             BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
	             for (;;) {
	                 String line = in.readLine();
	                 if (line == null) {
	                     continue;
	                 }
	                 /*
	                  * 向服务端发送在控制台输入的文本 并用"\r\n"结尾
	                  * 之所以用\r\n结尾 是因为我们在handler中添加了 DelimiterBasedFrameDecoder 帧解码。
	                  * 这个解码器是一个根据\n符号位分隔符的解码器。所以每条消息的最后必须加上\n否则无法识别和解码
	                  * */
	                 future.channel().writeAndFlush(line + "\r\n");
	             }
	         } finally {
	             // The connection is closed automatically on shutdown.
	        	 workGroup.shutdownGracefully();
	         }
	     }
}

②HelloClientInitializer.java

主要功能是完成客户端的编解码工作

public class HelloClientInitializer extends ChannelInitializer<SocketChannel> {

	     protected void initChannel(SocketChannel ch) throws Exception {
	         ChannelPipeline pipeline = ch.pipeline();

	         /*
	          * 这个地方的 必须和服务端对应上。否则无法正常解码和编码
	          *
	          * 解码和编码 我将会在下一张为大家详细的讲解。再次暂时不做详细的描述
	          *
	          * */
	         pipeline.addLast("framer", new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
	         pipeline.addLast("decoder", new StringDecoder());
	         pipeline.addLast("encoder", new StringEncoder());

	         // 客户端的逻辑
	         pipeline.addLast("handler", new HelloClientHandler());
	    }

}

③ HelloClientHandler.java

业务处理类,主要有三个方法

客户端建立连接时调用:channelActive方法

客户端接收服务端消息时调用:channelRead0方法

连接断开时调用:channelInactive方法

public class HelloClientHandler extends SimpleChannelInboundHandler<String> {
	     @Override
	     protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {

	         System.out.println("Server say : " + msg);
	     }

	     @Override
	     public void channelActive(ChannelHandlerContext ctx) throws Exception {
	         System.out.println("Client active ");
	         super.channelActive(ctx);
	     }

	     @Override
	     public void channelInactive(ChannelHandlerContext ctx) throws Exception {
	         System.out.println("Client close ");
	         super.channelInactive(ctx);
	     }
}

2.服务端

①HelloServer.java

public class HelloServer {
	 /**
     * 服务端监听的端口地址
     */
    private static final int portNumber = 7878;

    public static void main(String[] args) throws InterruptedException {
    	//第一个线程组用于接收client连接
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        //第二个线程组用于具体的业务处理
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
        	//创建一个辅助类Boosatrap用于对Server进行一系列的配置
            ServerBootstrap b = new ServerBootstrap();
            //将两个线程组加入进来
            b.group(bossGroup, workerGroup);
            //指定使用NioServerSocketChannel这种类型的通道
            b.channel(NioServerSocketChannel.class);
            //一定要使用childHandler绑定具体的事件处理器
            b.childHandler(new HelloServerInitializer());

            //SocketChannel通道的配置项(保持连接)
            b.option(ChannelOption.SO_KEEPALIVE, true);

            // 服务器绑定端口监听
            ChannelFuture f = b.bind(portNumber).sync();
            // 监听服务器关闭监听
            f.channel().closeFuture().sync();

            // 可以简写为
            /* b.bind(portNumber).sync().channel().closeFuture().sync(); */
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}

②HelloServerInitializer.java

主要功能是完成服务端的编解码工作

public class HelloServerInitializer extends ChannelInitializer<SocketChannel> {
	     @Override
	     protected void initChannel(SocketChannel ch) throws Exception {
	         ChannelPipeline pipeline = ch.pipeline();

	         // 以("\n")为结尾分割的 解码器
	         pipeline.addLast("framer", new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));

	         // 字符串解码 和 编码
	         pipeline.addLast("decoder", new StringDecoder());
	         pipeline.addLast("encoder", new StringEncoder());

	         // 自己的逻辑Handler
	         pipeline.addLast("handler", new HelloServerHandler());
	     }
}

③HelloServerHandler.java

服务端的业务处理类,主要包括channelRead0(),channelActive()方法

channelActive()建立连接时触发

channelRead0()接收客户端消息

public class HelloServerHandler extends SimpleChannelInboundHandler<String> {
	     @Override
	     protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
	         // 收到消息直接打印输出
	         System.out.println(ctx.channel().remoteAddress() + " Say : " + msg);

	         // 返回客户端消息 - 我已经接收到了你的消息
	         ctx.writeAndFlush("Received your message !\n");
	     }

	     /*
	      *
	      * 覆盖 channelActive 方法 在channel被启用的时候触发 (在建立连接的时候)
	      *
	      * channelActive 和 channelInActive 在后面的内容中讲述,这里先不做详细的描述
	      * */
	     @Override
	     public void channelActive(ChannelHandlerContext ctx) throws Exception {

	         System.out.println("RamoteAddress : " + ctx.channel().remoteAddress() + " active !");

	         ctx.writeAndFlush( "Welcome to " + InetAddress.getLocalHost().getHostName() + " service!\n");

	         super.channelActive(ctx);
	     }
}
时间: 2024-08-01 18:37:40

netty基本用法的相关文章

netty AttributeKey用法

final static AttributeKey<Integer> id = new AttributeKey<Integer>("ID");

Netty如何实现Reactor模式

在前面的文章中(Reactor模型详解),我们讲解了Reactor模式的各种演变形式,本文主要讲解的则是Netty是如何实现Reactor模式的.这里关于Netty实现的Reactor模式,需要说明的是,其实现的模式如下图所示: image.png 对于Netty使用的Reactor模式,其主要特点如下: 使用一个线程作为mainReactor,专门用于监听客户端的连接事件,当获取到事件之后就将该事件交由Acceptor处理,以获取客户端连接:在mainReactor获取客户端Channel之后

netty用法总结

/**decoder和encoder,如果不需要解析,就使用系统的 * ch.pipeline().addLast(new StringDecoder()); * ch.pipeline().addLast(new StringEncoder()); * 如果使用自己的规则解析,那就写自己的,就如下面 * ch.pipeline().addLast("decoder", new MyMessageDecoder()); *ch.pipeline().addLast("enco

【netty】Netty系列之Netty百万级推送服务设计要点

1. 背景 1.1. 话题来源 最近很多从事移动互联网和物联网开发的同学给我发邮件或者微博私信我,咨询推送服务相关的问题.问题五花八门,在帮助大家答疑解惑的过程中,我也对问题进行了总结,大概可以归纳为如下几类: Netty是否可以做推送服务器? 如果使用Netty开发推送服务,一个服务器最多可以支撑多少个客户端? 使用Netty开发推送服务遇到的各种技术问题. 由于咨询者众多,关注点也比较集中,我希望通过本文的案例分析和对推送服务设计要点的总结,帮助大家在实际工作中少走弯路. 1.2. 推送服务

ElasticSearch的基本用法与集群搭建

ElasticSearch的基本用法与集群搭建 一.简介 ElasticSearch和Solr都是基于Lucene的搜索引擎,不过ElasticSearch天生支持分布式,而Solr是4.0版本后的SolrCloud才是分布式版本,Solr的分布式支持需要ZooKeeper的支持. 这里有一个详细的ElasticSearch和Solr的对比:http://solr-vs-elasticsearch.com/ 二.基本用法 Elasticsearch集群可以包含多个索引(indices),每一个索

【转】Netty那点事(四)Netty与Reactor模式

[原文]https://github.com/code4craft/netty-learning/blob/master/posts/ch4-reactor.md 一:Netty.NIO.多线程? 时隔很久终于又更新了!之前一直迟迟未动也是因为积累不够,后面比较难下手.过年期间@李林锋hw发布了一个Netty5.0架构剖析和源码解读 http://vdisk.weibo.com/s/C9LV9iVqH13rW/1391437855,看完也是收获不少.前面的文章我们分析了Netty的结构,这次咱们

Netty系列之Netty可靠性分析

作者 李林锋 发布于 2014年6月19日 | 29 讨论 分享到:微博微信FacebookTwitter有道云笔记邮件分享 稍后阅读 我的阅读清单 1. 背景 1.1. 宕机的代价 1.1.1. 电信行业 毕马威国际(KPMG International)在对46个国家的74家运营商进行调查后发现,全球通信行业每年的收益流失约为400亿美元,占总收入的1%-3%.导致收益流失的因素有多种,主要原因就是计费BUG. 1.1.2. 互联网行业 美国太平洋时间8月16日下午3点50分到3点55分(北

Netty、NIO、多线程

一:Netty.NIO.多线程? 时隔很久终于又更新了!之前一直迟迟未动也是因为积累不够,后面比较难下手.过年期间@李林锋hw发布了一个Netty5.0架构剖析和源码解读,看完也是收获不少.前面的文章我们分析了Netty的结构,这次咱们来分析最错综复杂的一部分-Netty中的多线程以及NIO的应用. 理清NIO与Netty的关系之前,我们必须先要来看看Reactor模式.Netty是一个典型的多线程的Reactor模式的使用,理解了这部分,在宏观上理解Netty的NIO及多线程部分就不会有什么困

Netty权威指南

Netty权威指南(异步非阻塞通信领域的经典之作,国内首本深入剖析Netty的著作,全面系统讲解原理.实战和源码,带你完美进阶Netty工程师.) 李林锋 著   ISBN 978-7-121-23343-2 2014年6月出版 定价:79.00元 524页 16开 编辑推荐 - 资深一线专家诚意之作,总结多年实践经验,带你全面掌握Java高并发异步通信的首选框架——Netty. - Facebook.阿里巴巴.1号店.并发编程网.JBoss等多位资深技术专家联名力荐. <Netty权威指南>