netty客户端源码

随笔记录。

 

//创建一个ChannelFactory(客户端代码)

ChannelFactory factory = new NioClientSocketChannelFactory(

                  Executors.newCachedThreadPool(),

                  Executors.newCachedThreadPool());

// NioClientSocketChannelFactory构造方法

public NioClientSocketChannelFactory(

            Executor bossExecutor, Executor workerExecutor,

            int bossCount, int workerCount) {

        ...

        // 线程池

        this.bossExecutor = bossExecutor;

// 线程池

        this.workerExecutor = workerExecutor;

       // 构建ChannelSink,NioClientSocketPipelineSink实例

       // bossCount默认1,workerCount默认Runtime.getRuntime().availableProcessors() * 2

        sink = new NioClientSocketPipelineSink(

                bossExecutor, workerExecutor, bossCount, workerCount);

}

 

// NioClientSocketPipelineSink构造方法

NioClientSocketPipelineSink(Executor bossExecutor, Executor workerExecutor,

            int bossCount, int workerCount) {

        this.bossExecutor = bossExecutor;

      

        bosses = new Boss[bossCount];

        for (int i = 0; i < bosses.length; i ++) {

            bosses[i] = new Boss(i + 1);

        }

       

        workers = new NioWorker[workerCount];

        for (int i = 0; i < workers.length; i ++) {

            workers[i] = new NioWorker(id, i + 1, workerExecutor);

        }

}

 

// 创建Bootstrap并设置factory(客户端代码)

ClientBootstrap bootstrap = new ClientBootstrap(factory);

// Bootstrap类set方法

public void setFactory(ChannelFactory factory) {

        …

        this.factory = factory;

}

 

// 设置ChannelPipelineFactory,实现getPipeline方法,返回一个ChannelPipeline实现类

// (客户端代码)

bootstrap.setPipelineFactory(new ChannelPipelineFactory() {

              public ChannelPipeline getPipeline() {

                  ChannelPipeline pipeline = Channels.pipeline();

                  pipeline.addLast("encode",new StringEncoder());

                  pipeline.addLast("decode",new StringDecoder());

                  pipeline.addLast("handler1",new TimeClientHandler());

                  return pipeline;

              }

          });

DefaultChannelPipeline类addLast方法

public synchronized void addLast(String name, ChannelHandler handler) {

    if (name2ctx.isEmpty()) {

        // 初始化name2ctx,head,tail

        init(name, handler);

    } else {

        …

        DefaultChannelHandlerContext oldTail = tail;

        DefaultChannelHandlerContext    newTail =   new DefaultChannelHandlerContext(oldTail, null, name, handler);

        …

        // 最新的DefaultChannelHandlerContext放入tail以及更新到oldTail.next中

        oldTail.next = newTail;

        tail = newTail;

        name2ctx.put(name, newTail);

        …

    }

}

// 客户端发起连接请求(客户端代码)

bootstrap.connect (new InetSocketAddress("127.0.0.1", 8080));

// connect源代码解读

ClientBootstrap类connect方法

public ChannelFuture connect(final SocketAddress remoteAddress,

final SocketAddress localAddress) {

         …

        ChannelPipeline pipeline;

        try {

           // 返回 DefaultChannelPipeline对象实例

            pipeline = getPipelineFactory().getPipeline();

        } catch (Exception e) {

            throw new ChannelPipelineException("Failed to initialize a pipeline.", e);

        }

        // Set the options.

        // 返回NioClientSocketChannelFactory实例,并创建NioClientSocketChannel实例

        Channel ch = getFactory().newChannel(pipeline);

        ch.getConfig().setOptions(getOptions());

        // Bind.

        if (localAddress != null) {

            ch.bind(localAddress);

        }

        // Connect.

        return ch.connect(remoteAddress);

}

NioClientSocketChannelFactory类newChannel方法

public SocketChannel newChannel(ChannelPipeline pipeline) {

        //this为NioClientSocketChannelFactory实例

       //pipeline为DefaultChannelPipeline实例

       //sink为NioClientSocketPipelineSink实例

       // sink.nextWorker返回一个NioWorker实例

        return new NioClientSocketChannel(this, pipeline, sink, sink.nextWorker());

}

NioClientSocketChannel类构造方法

NioClientSocketChannel(

            ChannelFactory factory, ChannelPipeline pipeline,

            ChannelSink sink, NioWorker worker) {

        //  新创建一个SocketChannel(newSocket() = > SocketChannel.open())

        super(null, factory, pipeline, sink, newSocket(), worker);

        fireChannelOpen(this);

    }

继续看父类NioSocketChannel构造方法

public NioSocketChannel(

            Channel parent, ChannelFactory factory,

            ChannelPipeline pipeline, ChannelSink sink,

            SocketChannel socket, NioWorker worker) {

        super(parent, factory, pipeline, sink);

        this.socket = socket;

        this.worker = worker;

        config = new DefaultNioSocketChannelConfig(socket.socket());

}

继续看父类AbstractChannel构造方法

protected AbstractChannel(

            Channel parent, ChannelFactory factory,

            ChannelPipeline pipeline, ChannelSink sink) {

                   // 传入了一个null值

        this.parent = parent;

                   // NioClientSocketChannelFactory实例

        this.factory = factory;

                   // DefaultChannelPipeline实例

        this.pipeline = pipeline;

        id = allocateId(this);

        pipeline.attach(this, sink);

}

DefaultChannelPipeline类attach方法

public void attach(Channel channel, ChannelSink sink) {

        …

                   // NioClientSocketChannel实例

        this.channel = channel;

                   // NioClientSocketPipelineSink实例

        this.sink = sink;

}

 

// ClientBootstrap类connect方法中ch.connect(remoteAddress)

//类AbstractChannel

public ChannelFuture connect(SocketAddress remoteAddress) {

        return Channels.connect(this, remoteAddress);

}

//类Channels

public static ChannelFuture connect(Channel channel, SocketAddress remoteAddress) {

        if (remoteAddress == null) {

            throw new NullPointerException("remoteAddress");

        }

        ChannelFuture future = future(channel, true);

                   // DefaultChannelPipeline

                   // 新建一个ChannelState实例DownstreamChannelStateEvent

        channel.getPipeline().sendDownstream(new DownstreamChannelStateEvent(

                channel, future, ChannelState.CONNECTED, remoteAddress));

        return future;

}

//类NioClientSocketPipelineSink

public void eventSunk(

            ChannelPipeline pipeline, ChannelEvent e) throws Exception {

        if (e instanceof ChannelStateEvent) {

            ChannelStateEvent event = (ChannelStateEvent) e;

            NioClientSocketChannel channel =

                (NioClientSocketChannel) event.getChannel();

            ChannelFuture future = event.getFuture();

            ChannelState state = event.getState();

            Object value = event.getValue();

 

            switch (state) {

            case OPEN:

                if (Boolean.FALSE.equals(value)) {

                    channel.worker.close(channel, future);

                }

                break;

            case BOUND:

                if (value != null) {

                    bind(channel, future, (SocketAddress) value);

                } else {

                    channel.worker.close(channel, future);

                }

                break;

            case CONNECTED:

                if (value != null) {

                                               //第一次客户端发起连接

                    connect(channel, future, (SocketAddress) value);

                } else {

                    channel.worker.close(channel, future);

                }

                break;

            case INTEREST_OPS:

                channel.worker.setInterestOps(channel, future, ((Integer) value).intValue());

                break;

            }

        } else if (e instanceof MessageEvent) {

            MessageEvent event = (MessageEvent) e;

            NioSocketChannel channel = (NioSocketChannel) event.getChannel();

            boolean offered = channel.writeBuffer.offer(event);

            assert offered;

            channel.worker.writeFromUserCode(channel);

        }

}

private void connect(

            final NioClientSocketChannel channel, final ChannelFuture cf,

            SocketAddress remoteAddress) {

        try {

// channel.socket在初始化NioClientSocketChannel时创建

//nio发起连接,因为设置了socket.configureBlocking(false)

//connect方法立即返回,返回值为false

//此时服务端已经收到了客户端发送的connect事件并进行处理

            if (channel.socket.connect(remoteAddress)) {

                channel.worker.register(channel, cf);

            } else {

                channel.getCloseFuture().addListener(new ChannelFutureListener() {

                    public void operationComplete(ChannelFuture f)

                            throws Exception {

                        if (!cf.isDone()) {

                            cf.setFailure(new ClosedChannelException());

                        }

                    }

                });

                cf.addListener(ChannelFutureListener.CLOSE_ON_FAILURE);

                channel.connectFuture = cf;

                                     //注册事件,nextBoss()返回一个Runnable实例

                nextBoss().register(channel);

            }

 

        } catch (Throwable t) {

            cf.setFailure(t);

            fireExceptionCaught(channel, t);

            channel.worker.close(channel, succeededFuture(channel));

        }

}

// Boss内部类 NioClientSocketPipelineSink

void register(NioClientSocketChannel channel) {

    Runnable registerTask = new RegisterTask(this, channel);

    Selector selector;

 

    synchronized (startStopLock) {

        if (!started) {

            // Open a selector if this worker didn't start yet.

            try {

                // 打开一个选择器

                this.selector = selector =  Selector.open();

            } catch (Throwable t) {

                throw new ChannelException(

                        "Failed to create a selector.", t);

            }

 

            // Start the worker thread with the new Selector.

            boolean success = false;

            try {

                //启动线程,消费任务队列

//bossExecutor是客户端代码Executors.newCachedThreadPool()所创建

// nio的selector.select(500)操作

                DeadLockProofWorker.start(

                        bossExecutor,

                        new ThreadRenamingRunnable(

                                this, "New I/O client boss #" + id + '-' + subId));

                success = true;

            } finally {

                if (!success) {

                    // Release the Selector if the execution fails.

                    try {

                        selector.close();

                    } catch (Throwable t) {

                        logger.warn("Failed to close a selector.", t);

                    }

                    this.selector = selector = null;

                    // The method will return to the caller at this point.

                }

            }

        } else {

            // Use the existing selector if this worker has been started.

            selector = this.selector;

        }

 

        assert selector != null && selector.isOpen();

 

        started = true;

        //写入队列一个注册任务

        boolean offered = registerTaskQueue.offer(registerTask);

        assert offered;

    }

 

    if (wakenUp.compareAndSet(false, true)) {

        selector.wakeup();

    }

}

//类DeadLockProofWorker

public static void start(final Executor parent, final Runnable runnable) {

  //parent为bossExecutor,即一个线程池

        ......

//开启一个子线程

        parent.execute(new Runnable() {

            public void run() {

                PARENT.set(parent);

                try {

                   // ThreadRenamingRunnable实例

                    runnable.run();

                } finally {

                    PARENT.remove();

                }

            }

        });

}

//类ThreadRenamingRunnable

public void run() {

       ......

        // Run the actual runnable and revert the name back when it ends.

        try {

          //runnable为Boss实例

            runnable.run();

        } finally {

            if (renamed) {

                // Revert the name back if the current thread was renamed.

                // We do not check the exception here because we know it works.

                currentThread.setName(oldThreadName);

            }

        }

}

// Boss内部类 NioClientSocketPipelineSink中

public void run() {

    boolean shutdown = false;

    Selector selector = this.selector;

    long lastConnectTimeoutCheckTimeNanos = System.nanoTime();

    for (;;) {

        wakenUp.set(false);

 

        try {

            // 设置超时阻塞

            int selectedKeyCount = selector.select(500);

 

            if (wakenUp.get()) {

                selector.wakeup();

            }

            // 消费队列中的事件

            //nio中register操作

            processRegisterTaskQueue();

 

            if (selectedKeyCount > 0) {

                //处理选择器获取到的事件

                processSelectedKeys(selector.selectedKeys());

            }

            ……

        } catch (Throwable t) {

           ……

        }

    }

}

 

private void processRegisterTaskQueue() {

for (;;) {

         //获取事件,task为registerTaskQueue.offer(registerTask);RegisterTask实例

        final Runnable task = registerTaskQueue.poll();

        if (task == null) {

            break;

        }

       //执行NioClientSocketPipelineSink中的内部类RegisterTask的Run方法

        task.run();

    }

}

 

//内部类RegisterTask NioClientSocketPipelineSink中

public void run() {

try {

         // nio socket注册,只有完成注册以后,才能和服务端进行通信

        channel.socket.register(

                boss.selector, SelectionKey.OP_CONNECT, channel);

    } catch (ClosedChannelException e) {

        channel.worker.close(channel, succeededFuture(channel));

    }

   ……

}

private void processSelectedKeys(Set<SelectionKey> selectedKeys) {

    for (Iterator<SelectionKey> i = selectedKeys.iterator(); i.hasNext();) {

        SelectionKey k = i.next();

        i.remove();

 

        if (!k.isValid()) {

            close(k);

            continue;

        }

 

        if (k.isConnectable()) {

            //完成客户端连接

            connect(k);

        }

    }

}

 

private void connect(SelectionKey k) {

    NioClientSocketChannel ch = (NioClientSocketChannel) k.attachment();

try {

         //nio完成客户端连接

        if (ch.socket.finishConnect()) {

            k.cancel();

            //NioWorker类注册

            ch.worker.register(ch, ch.connectFuture);

        }

    } catch (Throwable t) {

       .......

    }

}

 

类NioWorker负责读写事件注册处理

未完待续...

posted @ 2016-11-17 13:40  小N~  阅读(1559)  评论(0编辑  收藏  举报