《netty》netty原始碼分析之ChannelPipeline和ChannelHandler
阿新 • • 發佈:2018-12-24
ChannelPipeline
ChannelPipeline是ChannelHandler的容器,他負責ChannelHandler的事件攔截.
@Override public final ChannelPipeline addLast(EventExecutorGroup group, String name, ChannelHandler handler) { final AbstractChannelHandlerContext newCtx; synchronized (this) { checkMultiplicity(handler); newCtx = newContext(group, filterName(name, handler), handler); addLast0(newCtx); // If the registered is false it means that the channel was not registered on an eventloop yet. // In this case we add the context to the pipeline and add a task that will call // ChannelHandler.handlerAdded(...) once the channel is registered. if (!registered) { newCtx.setAddPending(); callHandlerCallbackLater(newCtx, true); return this; } EventExecutor executor = newCtx.executor(); if (!executor.inEventLoop()) { newCtx.setAddPending(); executor.execute(new Runnable() { @Override public void run() { callHandlerAdded0(newCtx); } }); return this; } } callHandlerAdded0(newCtx); return this; }
private void addLast0(AbstractChannelHandlerContext newCtx) {
AbstractChannelHandlerContext prev = tail.prev;
newCtx.prev = prev;
newCtx.next = tail;
prev.next = newCtx;
tail.prev = newCtx;
}
ChannelHandler
看個例子
/** * * Title: HelloServerHandler * Description: 服務端業務邏輯 * Version:1.0.0 * @author guokaige * @date 2017-8-31 */ public class NettyServerHandler extends SimpleChannelInboundHandler<String> { /* * 收到訊息時,返回資訊 */ @Override protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception { // 收到訊息直接列印輸出 System.out.println("服務端接受的訊息 : " + msg); if("quit".equals(msg)){//服務端斷開的條件 ctx.close(); } Date date=new Date(); // 返回客戶端訊息 ctx.writeAndFlush(date+"\n"); } /* * 建立連線時,返回訊息 */ @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { System.out.println("連線的客戶端地址:" + ctx.channel().remoteAddress()); ctx.writeAndFlush("客戶端"+ InetAddress.getLocalHost().getHostName() + "成功與服務端建立連線! \n"); super.channelActive(ctx); } }