Netty实战读书笔记(第八章)

当server相应client的请求时,有时候需要server作为client向其他server请求资源,这个时候一般通过再创建新的bootstrap,添加新的EventLoopgroup,,这种做法创建新的线程,会有线程创建和切换的开销,并且会有client 线程和server线程的数据交换,所有可以通过将server的EventLoop Group到client的bootstrap中,这样实现线程复用。

import java.net.InetSocketAddress;

import io.netty.bootstrap.Bootstrap;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;

/**
 * 当处理client的请求时,需要server作为client向其他server请求,这时这个server作为client,因为一个EventLoop为一个线程,共享EventLoop不需要创建新的线程,没有上下文切换的开销,server作为另一个client,没有数据传输的问题。
 * @author pc
 *
 */
public class BootstrapEventLoopGroup {
	
	public void bootstrap(){
		NioEventLoopGroup group = new NioEventLoopGroup();
		try{
			ServerBootstrap boot = new ServerBootstrap();
			boot.group(group)
			.channel(NioServerSocketChannel.class)// 指定channel为NioServerSocketChannel
			.childHandler(new SimpleChannelInboundHandler<ByteBuf>(){
				ChannelFuture future;
				@Override
				public void channelActive(ChannelHandlerContext ctx ){
					System.out.println("连接成功!");
					// 将server已经存在的EventLoop传入server 作为client的EventLoopGroup。不用新建EventGroup。
					Bootstrap client = new Bootstrap();
					client.group(ctx.channel().eventLoop());// 将server的EventLoop传递给client的group。这样可以不用创创建新的开销。
					client.channel(NioSocketChannel.class);
					future = client.connect(new InetSocketAddress("www.manning.com" , 80));
					
					
				}
				
				@Override
				protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {
					// TODO Auto-generated method stub
					if (future.isDone()){// 如果server作为client已经连接好了。
						
					}
				}
				
			});
			ChannelFuture future = boot.bind(new InetSocketAddress(8000));// 绑定到指定端口
			future.addListener(new ChannelFutureListener(){

				@Override
				public void operationComplete(ChannelFuture future) throws Exception {
					// TODO Auto-generated method stub
					if (future.isDone()){
						System.out.println("server complete.");
					}
				}
				
			});
		} finally{
			
		}
	}
	
}
在引导过程中添加多个ChannelHandler。

channelInitializer可以向pipeline添加多个ChannelHandler,向channel注册实现ChannelInitializer的实例,之后会调用override的initChannel()的方法,通过向channel添加多个channelHandler。

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpClientCodec;
import io.netty.handler.codec.http.HttpObjectAggregator;

public class BootstrapWithInitializer {
	
	public void boostrap(){
		
		ServerBootstrap bootstrap = new ServerBootstrap();
		bootstrap.group(new NioEventLoopGroup() , new NioEventLoopGroup() )
		.channel(NioServerSocketChannel.class)// 指定channel
		.childHandler(new InitializerImp());// 注册channelInitializer,设置多个channelHandler。
	}
	// 设置initializerImp自定义的channelHandler。
	private class InitializerImp extends ChannelInitializer<Channel>{

		@Override
		protected void initChannel(Channel ch) throws Exception {
			// TODO Auto-generated method stub
			ChannelPipeline pipeline = ch.pipeline();
			pipeline.addLast(new HttpClientCodec());
			pipeline.addLast(new HttpObjectAggregator(Integer.MAX_VALUE));
		}
		
	}
}
通过设置simpleChannelInboundHandler<DatagramPacket>设置Netty为无连接请求。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值