Netty入门 与 Java集成

简介

Netty我感觉不用太多介绍了,既然搜到了本篇文章,说明你对Netty已经有大体的认识。我就简单的介绍下。
首先Netty是一个高性能框架,单机可以支撑几十万甚至上百万的连接。
Netty 对 JDK 自带的 NIO 的 API 进行了良好的封装,解决了上述问题。且Netty拥有高性能、 吞吐量更高,延迟更低,减少资源消耗,最小化不必要的内存复制等优点。
Netty 现在都在用的是4.x,5.x版本已经废弃,Netty 4.x 需要JDK 6以上版本支持

集成Java

废话不多说,下面进入正题。

第一步

引入pom.xml依赖

<dependency>
    <groupId>io.netty</groupId>
    <artifactId>netty-all</artifactId>
    <version>4.1.54.Final</version>
</dependency>

第二步

实现服务端和客户端。
服务端

package com.netty.server;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;

public class NettyServer {
	public static void main(String[] args) {
		// 创建两个线程组bossGroup和workerGroup, 含有的子线程NioEventLoop的个数默认为cpu核数的两倍
		// bossGroup只是处理连接请求 ,真正的和客户端业务处理,会交给workerGroup完成
		EventLoopGroup bossGroup = new NioEventLoopGroup(1);
		EventLoopGroup workerGroup = new NioEventLoopGroup();
		try {
			// 创建服务器端的启动对象
			ServerBootstrap bootstrap = new ServerBootstrap();
			// 使用链式编程来配置参数
			bootstrap.group(bossGroup, workerGroup); // 设置两个线程组
			bootstrap.channel(NioServerSocketChannel.class); // 使用NioServerSocketChannel作为服务器的通道 实现
			// 初始化服务器连接队列大小,服务端处理客户端连接请求是顺序处理的,所以同一时间只能处理一 个客户端连接。
			// 多个客户端同时来的时候,服务端将不能处理的客户端连接请求放在队列中等待处理
			bootstrap.option(ChannelOption.SO_BACKLOG, 1024);

			bootstrap.childHandler(new ChannelInitializer<Channel>() {// 创建通道初始化对象,设置初始化参数
				@Override
				protected void initChannel(Channel ch) throws Exception {
					 对workerGroup的SocketChannel设置处理器codec
					ch.pipeline().addLast(new NettyServerHandler());
				}
			});

			System.out.println("netty server start。。");
			// 绑定一个端口并且同步, 生成了一个ChannelFuture异步对象,通过isDone()等方法可以判断异步 事件的执行情况
			// 启动服务器(并绑定端口),bind是异步操作,sync方法是等待异步操作执行完毕
			ChannelFuture cf = bootstrap.bind(9000).sync();
			// 对通道关闭进行监听,closeFuture是异步操作,监听通道关闭
			// 通过sync方法同步等待通道关闭处理完毕,这里会阻塞等待通道关闭完成
			cf.channel().closeFuture().sync();
		} catch (Exception e) {

		} finally {
			bossGroup.shutdownGracefully();
			workerGroup.shutdownGracefully();
		}
	}
}
package com.netty.server;

import java.nio.charset.Charset;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;

/**
 * 
 * 自定义Handler需要继承netty规定好的某个HandlerAdapter(规范)
 * 
 * @author AdminMall
 *
 */
public class NettyServerHandler extends ChannelInboundHandlerAdapter {

	/**
	 * 读取客户端发送过来的数据
	 * 
	 * @param ctx 上下文对象, 含有通道channel,管道pipeline
	 * @param msg 就是客户端发送的数据
	 * 
	 */
	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
		System.out.println("服务器读取线程" + Thread.currentThread().getName());
		// 将 msg 转成一个 ByteBuf,类似NIO 的 ByteBuffer
		ByteBuf byteBuf = (ByteBuf) msg;
		System.out.println("客户端发送的消息为:" + byteBuf.toString(CharsetUtil.UTF_8));
	}

	/**
	 * 数据读取完毕处理方法
	 * 
	 * @param ctx
	 * @throws Exception
	 * 
	 * 
	 */
	@Override
	public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
		// 在数据读取完毕后,向客户端发送消息
		ByteBuf buf = Unpooled.copiedBuffer("HelloClient", CharsetUtil.UTF_8);
		ctx.writeAndFlush(buf);
	}

}

客户端

package com.netty.client;

import com.netty.server.NettyServerHandler;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;

public class NettyClient {
	public static void main(String[] args) {
		// 客户端需要一个事件循环组
		EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
		try {
			// 创建客户端启动对象
			// 注意客户端使用的不是 ServerBootstrap 而是 Bootstrap
			Bootstrap bootstrap = new Bootstrap();
			// 设置相关参数
			// 设置线程组
			bootstrap.group(eventLoopGroup);
			// 使用 NioSocketChannel 作为客户端的通道实现
			bootstrap.channel(NioSocketChannel.class);
			// 綁定毀掉
			bootstrap.handler(new ChannelInitializer<Channel>() {
				@Override
				protected void initChannel(Channel ch) throws Exception {
					// 加入处理器
					ch.pipeline().addLast(new NettyClientHandler());

				}
			});
			System.out.println("netty client start");
			// 启动客户端去连接服务器端
			ChannelFuture channelFuture = bootstrap.connect("127.0.0.1", 9000).sync();
			// 对关闭通道进行监听
			channelFuture.channel().closeFuture().sync();
		} catch (Exception e) {

		} finally {
			eventLoopGroup.shutdownGracefully();
		}

	}
}
package com.netty.client;

import java.nio.charset.Charset;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;

/**
 * 
 * 自定义Handler需要继承netty规定好的某个HandlerAdapter(规范)
 * 
 * @author AdminMall
 *
 */
public class NettyClientHandler extends ChannelInboundHandlerAdapter {

	/**
	 * 当客户端连接服务器完成就会触发该方法
	 * 
	 * @param ctx
	 * @throws Exception
	 * 
	 */
	@Override
	public void channelActive(ChannelHandlerContext ctx) throws Exception {
		// 向服务端发送消息
		ByteBuf byteBuf = Unpooled.copiedBuffer("HelloServer", CharsetUtil.UTF_8);
		ctx.writeAndFlush(byteBuf);
	}

	/**
	 * 读取客户端发送过来的数据
	 * 
	 * @param ctx 上下文对象, 含有通道channel,管道pipeline
	 * @param msg 就是客户端发送的数据
	 * 
	 */
	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
		// 将 msg 转成一个 ByteBuf,类似NIO 的 ByteBuffer
		ByteBuf byteBuf = (ByteBuf) msg;
		System.out.println("服务端发送的消息为:" + byteBuf.toString(CharsetUtil.UTF_8));
		System.out.println("服务端地址为:" + ctx.channel().remoteAddress());
	}

	/**
	 * 数据读取完毕处理方法
	 * 
	 * @param ctx
	 * @throws Exception
	 * 
	 * 
	 */
	@Override
	public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
		// 在数据读取完毕后,向客户端发送消息
		ByteBuf buf = Unpooled.copiedBuffer("HelloClient", CharsetUtil.UTF_8);
		ctx.writeAndFlush(buf);
	}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

铁蛋的铁,铁蛋的蛋

留一杯咖啡钱给作者吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值