`

Netty学习

 
阅读更多
Netty是一个基于JAVA NIO类库的异步通信框架,它的架构特点是:异步非阻塞、基于事件驱动、高性能、高可靠性和高可定制性。
在Netty中Client和Server通过Channel连接,然后通过ByteBuffer进行传输。每个Channel有自己的Pipeline,Pipeline上面可以添加和定义Handler和Event





Netty 4.0中,定义了Channel接口,这个接口用于连接网络的socket传输,或者具有I/O操作的组件连接。这里的I/O操作有,read,write,bind,connect.

Channel接口为用户提供了:

1.   Channel的当前状态,比如:Channel是否open,或者Channel是否已经连接。

2.   Channel的参数,比如:接受的buffer大小。

3.   Channel支持的I/O操作,比如:read,write,connect,bind。

4.   注册在Channel上的ChannelPipeline,ChannelPipeline用于处理所有的I/O事件和请求


ChannelHandler接口用于处理和拦截Channel接口中的ChannelEvents。Netty中的ChannelPipeline概念使用了Intecepting Filter Patter模式来实现,这样做的好处是允许用户可以完全控制Event的处理,并且控制ChannelHandlers在ChannelPipeline的交互。

当一个全新的Channel创建的时候,都必须创建一个ChannelPipeline,并使Channel和ChannelPipeline相关联。这种关联关系是永久性的,这意味着,一旦一个ChannelPipeline和Channel关联了,那么这个Channel就再也无法关联其他ChannelPipeline,也无法取消与当前ChannelPipeline的关联。

【官方推荐】使用Channel接口中的pipeleine()方法来创建一个ChannelPipelien,而不要用new去实例一个ChannePipeline类

ChannelPipeline pipeline = Channels.pipeline();


Pipeline中的事件流



图中显示了一个典型的ChannelHandler或者ChannelPipeline对于ChannelEvent的处理流程。ChannelHandler接口有两个子类,分别是ChannelUpstreamHandler(ChannelInboundHandler)和ChannelDownstreamHandler(ChannelOutBoundstreamHandler)。这两个之类用于处理每一个ChannelEvent,然后由ChannelHandlerContext.sendUpstream(ChannelEvent)和ChannelHandlerContext.sendDownstream(ChannelEvent)将每一个ChannelEvent转发到最近的handler。根据upstream和downstream的不同,每个Event的处理也会有所不同。

在一条Pipeline中,一般会有一个或者多个ChannelHandler用于接收I/O事件(read)或者请求I/O操作(write,close)。一个典型的服务器会有如下的一个ChannelPipeline用于处理不同的ChannelHandler。

ChannelPipeline p = Channels.pipeline();

p.addLast(“1”, new UpstreamHandlerA());

p.addList(“2”, new UpstreamHandlerB());

p.addList(“3”, new DownstreamHandlerA());

p.addList(“4”, new DownstreamHandlerB());

p.addList(“5”, new UpstreamHandlerX());


第一个Netty例子:

服务端

/**
 * Netty 服务端代码
 * 
 * @author lihzh
 * @alia OneCoder
 * @blog http://www.coderli.com
 */
public class HelloServer {

	public static void main(String args[]) {
		// Server服务启动器
		ServerBootstrap bootstrap = new ServerBootstrap(
				new NioServerSocketChannelFactory(
						Executors.newCachedThreadPool(),
						Executors.newCachedThreadPool()));
		// 设置一个处理客户端消息和各种消息事件的类(Handler)
//两个线程池一个用于监听请求,并分派给slave进行处  一个用于处理请求,将其丢到线程池中处
		bootstrap
				.setPipelineFactory(new ChannelPipelineFactory() {
					@Override
					public ChannelPipeline getPipeline()
							throws Exception {
						return Channels
								.pipeline(new HelloServerHandler());
					}
				});
		// 开放8000端口供客户端访问。
		bootstrap.bind(new InetSocketAddress(8000));
	}

	private static class HelloServerHandler extends
			SimpleChannelHandler {

		/**
		 * 当有客户端绑定到服务端的时候触发,打印"Hello world, I'm server."
		 * 
		 * @alia OneCoder
		 * @author lihzh
		 */
		@Override
		public void channelConnected(
				ChannelHandlerContext ctx,
				ChannelStateEvent e) {
			System.out.println("Hello world, I'm server.");
		}
	}
}



客户端

/**
 * Netty 客户端代码
 * 
 * @author lihzh
 * @alia OneCoder
 * @blog http://www.coderli.com
 */
public class HelloClient {

	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 HelloClientHandler());
			}
		});
		// 连接到本地的8000端口的服务端
		bootstrap.connect(new InetSocketAddress(
				"127.0.0.1", 8000));
	}

	private static class HelloClientHandler extends SimpleChannelHandler {


		/**
		 * 当绑定到服务端的时候触发,打印"Hello world, I'm client."
		 * 
		 * @alia OneCoder
		 * @author lihzh
		 */
		@Override
		public void channelConnected(ChannelHandlerContext ctx,
				ChannelStateEvent e) {
			System.out.println("Hello world, I'm client.");
		}
	}
}


Server端开放端口,供Client连接,Client发起请求,连接到Server指定的端口,完成绑定。随后便可自由通信。其实就是普通Socket连接通信的过程。
Netty框架是基于事件机制的,简单说,就是发生什么事,就找相关处理方法。就跟着火了找119,生病了找120一个道理。

Server
import org.jboss.netty.bootstrap.ClientBootstrap;
import org.jboss.netty.channel.*;
import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
import org.jboss.netty.handler.codec.string.StringDecoder;
import org.jboss.netty.handler.codec.string.StringEncoder;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.util.concurrent.Executors;


public class HelloNettyClient {

	public static void main(String[] args) {
		// Configure the client.
		ClientBootstrap bootstrap = new ClientBootstrap(
				new NioClientSocketChannelFactory(
						Executors.newCachedThreadPool(),
						Executors.newCachedThreadPool()));

		// Set up the default event pipeline.
		bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
			@Override
			public ChannelPipeline getPipeline() throws Exception {
				return Channels.pipeline(new StringDecoder(),
						new StringEncoder(), new ClientHandler());
			}
		});

		// Start the connection attempt.
		ChannelFuture future = bootstrap.connect(new InetSocketAddress(
				"localhost", 8000));

		// Wait until the connection is closed or the connection attempt fails.
		future.getChannel().getCloseFuture().awaitUninterruptibly();

		// Shut down thread pools to exit.
		bootstrap.releaseExternalResources();
	}

	private static class ClientHandler extends SimpleChannelHandler {
		private BufferedReader sin = new BufferedReader(new InputStreamReader(
				System.in));
		@Override
		public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
				throws Exception {
			if (e.getMessage() instanceof String) {
				String message = (String) e.getMessage();
				System.out.println(message);

				e.getChannel().write(sin.readLine());

				System.out.println("\n等待客户端输入。。。");
			}

			super.messageReceived(ctx, e);
		}

		@Override
		public void channelConnected(ChannelHandlerContext ctx,
				ChannelStateEvent e) throws Exception {
			System.out.println("已经与Server建立连接。。。。");
			System.out.println("\n请输入要发送的信息:");
			super.channelConnected(ctx, e);

			e.getChannel().write(sin.readLine());
		}
	}
};


Client

import org.jboss.netty.bootstrap.ClientBootstrap;
import org.jboss.netty.channel.*;
import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
import org.jboss.netty.handler.codec.string.StringDecoder;
import org.jboss.netty.handler.codec.string.StringEncoder;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.util.concurrent.Executors;


public class HelloNettyClient {

	public static void main(String[] args) {
		// Configure the client.
		ClientBootstrap bootstrap = new ClientBootstrap(
				new NioClientSocketChannelFactory(
						Executors.newCachedThreadPool(),
						Executors.newCachedThreadPool()));

		// Set up the default event pipeline.
		bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
			@Override
			public ChannelPipeline getPipeline() throws Exception {
				return Channels.pipeline(new StringDecoder(),
						new StringEncoder(), new ClientHandler());
			}
		});

		// Start the connection attempt.
		ChannelFuture future = bootstrap.connect(new InetSocketAddress(
				"localhost", 8000));

		// Wait until the connection is closed or the connection attempt fails.
		future.getChannel().getCloseFuture().awaitUninterruptibly();

		// Shut down thread pools to exit.
		bootstrap.releaseExternalResources();
	}

	private static class ClientHandler extends SimpleChannelHandler {
		private BufferedReader sin = new BufferedReader(new InputStreamReader(
				System.in));
		@Override
		public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
				throws Exception {
			if (e.getMessage() instanceof String) {
				String message = (String) e.getMessage();
				System.out.println(message);

				e.getChannel().write(sin.readLine());

				System.out.println("\n等待客户端输入。。。");
			}

			super.messageReceived(ctx, e);
		}

		@Override
		public void channelConnected(ChannelHandlerContext ctx,
				ChannelStateEvent e) throws Exception {
			System.out.println("已经与Server建立连接。。。。");
			System.out.println("\n请输入要发送的信息:");
			super.channelConnected(ctx, e);

			e.getChannel().write(sin.readLine());
		}
	}
};
  • 大小: 18.2 KB
  • 大小: 46.7 KB
分享到:
评论
发表评论

文章已被作者锁定,不允许评论。

相关推荐

    Netty学习资料.zip

    这个“Netty学习资料.zip”压缩包包含了韩顺平老师关于 Netty 的一系列教学资源,包括资料、笔记、课件、代码和软件,这些都是深入理解和实践 Netty 技术的重要参考资料。 首先,资料部分可能包含了一些关于 Netty ...

    Netty全套学习资源(包括源码、笔记、学习文档等)

    本资源包包含 Netty 的全方位学习材料,包括源码、笔记和学习文档,旨在帮助开发者深入理解和掌握 Netty。 一、Netty 源码解析 Netty 的源码是理解其工作原理的关键。通过阅读源码,我们可以了解到 Netty 如何实现...

    java netty学习资料

    这个学习资料包“java netty学习资料”很可能是为了帮助开发者理解和掌握Netty的核心概念和实践应用。 在Netty中,定义消息协议通讯是构建网络应用的关键步骤。Netty提供了一种灵活的方式来定义自定义的编解码器,...

    netty学习之ServerChannel

    Netty学习之ServerChannel Netty是一个高性能、异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端。在本篇中,我们将深入探讨ServerChannel这一核心概念,它是Netty中用于接收客户端...

    netty学习资料001

    这个“netty学习资料001”压缩包可能是为了帮助初学者或有经验的开发者深入理解Netty的工作原理和用法。下面我们将详细探讨Netty的核心概念、特性以及它在实际应用中的价值。 一、Netty简介 Netty最初由JBOSS团队...

    Netty学习笔记_Springboot实现自定义协议.docx

    Netty学习笔记_Springboot实现自定义协议 本文主要介绍了使用Netty框架在Springboot项目中实现自定义协议的方法。自定义协议是指在网络通信中,使用特定的数据格式来传输数据,以满足特定的业务需求。在本文中,...

    Netty学习与实战Demo-netty-learn.zip

    这个“Netty学习与实战Demo-netty-learn.zip”压缩包显然是为帮助学习者深入理解和实践Netty而准备的。下面将详细探讨Netty的核心概念、关键特性以及如何通过提供的示例进行学习。 1. **Netty核心概念** - **NIO...

    netty学习demo(初学代码结构+固定消息+自定义分隔符+自定义协议+心跳+http+序列化压缩+自动断线)

    总的来说,这个“netty学习demo”覆盖了Netty开发的多个重要方面,对于初学者来说是一份非常有价值的实践资料。通过深入理解并实践这些示例,你将能够更好地掌握Netty的使用,并能灵活地应用于各种网络通信场景。

    netty学习资料(java源代码实例).zip

    这个“netty学习资料(java源代码实例).zip”压缩包包含的资源显然是为了帮助Java开发者深入理解并实践Netty框架。在Netty的学习过程中,源代码实例是极其宝贵的,因为它们能让你直观地看到如何在实际应用中运用Netty...

    netty学习之心跳.rar

    在“netty学习之心跳.rar”这个压缩包中,包含的是关于Netty如何实现心跳处理的示例代码,分别针对Netty 3和Netty 5两个版本。心跳机制在网络通信中扮演着至关重要的角色,它确保了连接的活跃性,并能及时检测到网络...

    Netty权威指南完整版高清pdf

    总的来说,《Netty权威指南》是一本全面且深入的Netty学习资料,无论你是初学者还是有经验的开发者,都能从中获益,提升你的网络编程技能,为构建高性能、低延迟的网络应用打下坚实基础。通过阅读这本书,你将能够...

    netty-netty-4.1.19.Final.zip_netty_netty学习_rocketmq

    Netty 是一个高性能、异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端。...深入学习和理解Netty,不仅能够帮助你更好地使用RocketMQ,也有助于你在其他领域开发高性能的网络应用。

    netty学习教程

    这个“netty学习教程”压缩包包含了19个PDF文档,旨在全面介绍Netty的基础知识以及实际应用。以下是根据这些文档标题和描述可能涵盖的主要知识点: 1. **Netty基础** - Netty架构:理解Netty的核心组件,如Event...

    Netty基础,用于学习Netty,参考黑马程序员的netty教程

    Netty基础,用于学习Netty,参考黑马程序员的netty教程

    netty学习视频共92课(质量超高)

    netty学习视频共92将(质量超高,质量不高来砍我)

    读书笔记:netty 学习《Netty权威指南》第2版.zip

    读书笔记:netty 学习《Netty权威指南》第2版

    netty学习资料,从入门到进阶

    netty学习资料,从入门到进阶

    读书笔记:Netty学习与实战Demo.zip

    读书笔记:Netty学习与实战Demo

Global site tag (gtag.js) - Google Analytics