netty3.6.6 源码片段 - ChannelPipeline

4 篇文章 0 订阅

代码

package cn.java.netty3_6_6.internal.pipeline;

import java.util.HashMap;
import java.util.Map;


public class DefaultChannelPipelineTest {

    public static void main(String[] args) throws InterruptedException {
        DefaultChannelPipeline channelPipeline = new DefaultChannelPipeline();

        // 添加成员
        channelPipeline.addLast("fooOneChannelUpstreamHandler", new FooOneChannelUpstreamHandler());
        channelPipeline.addLast("fooTwoChannelUpstreamHandler", new FooTwoChannelUpstreamHandler());

        // 附加对象
        channelPipeline.attach(new NioServerSocketPipelineSink());

        // 发送流
        channelPipeline.sendUpstream(new UpstreamMessageEvent("name0"));
    }

    /**
     * 事件
     */
    public interface ChannelEvent {
    }

    public static class UpstreamMessageEvent implements ChannelEvent {
        private String name;

        public UpstreamMessageEvent(String name) {
            this.name = name;
        }
    }

    /**
     *
     */
    public interface ChannelSink {
        void eventSunk(ChannelPipeline pipeline, ChannelEvent e) throws Exception;
    }

    static class NioServerSocketPipelineSink implements ChannelSink {
        public void eventSunk(ChannelPipeline pipeline, ChannelEvent e) throws Exception {

        }
    }

    /**
     * 处理器上下文
     */
    public interface ChannelHandlerContext {
        /**
         *
         */
        void sendUpstream(ChannelEvent e);

        /**
         *
         */
        void sendDownstream(ChannelEvent e);
    }

    /**
     * 管道
     */
    public interface ChannelPipeline {
    }

    /**
     * 处理器
     */
    public interface ChannelHandler {
    }

    public interface ChannelUpstreamHandler extends ChannelHandler {
        void handleUpstream(ChannelHandlerContext ctx, ChannelEvent e) throws Exception;
    }

    public interface ChannelDownstreamHandler extends ChannelHandler {
        void handleDownstream(ChannelHandlerContext ctx, ChannelEvent e) throws Exception;
    }

    static class FooOneChannelUpstreamHandler implements ChannelUpstreamHandler {
        @Override
        public void handleUpstream(ChannelHandlerContext ctx, ChannelEvent e) throws Exception {
            // todo something
            System.out.println("hello, this is " + getClass());
            ctx.sendUpstream(e); // 触发下一个handler
        }
    }

    static class FooTwoChannelUpstreamHandler implements ChannelUpstreamHandler {
        @Override
        public void handleUpstream(ChannelHandlerContext ctx, ChannelEvent e) throws Exception {
            // todo something
            System.out.println("hello, this is " + getClass());
            ctx.sendUpstream(e); // 触发下一个handler
        }
    }


    private static class DefaultChannelPipeline implements ChannelPipeline {
        private final Map<String, DefaultChannelHandlerContext> name2ctx = new HashMap<String, DefaultChannelHandlerContext>(4);
        private volatile ChannelSink sink;
        private volatile DefaultChannelHandlerContext head;
        private volatile DefaultChannelHandlerContext tail;
        static final ChannelSink discardingSink = new DiscardingChannelSink();

        public ChannelSink getSink() {
            ChannelSink sink = this.sink;
            if (sink == null) {
                return discardingSink;
            }
            return sink;
        }

        public void attach(ChannelSink sink) {
            if (sink == null) {
                throw new NullPointerException("sink");
            }
            this.sink = sink;
        }

        public synchronized void addLast(String name, ChannelHandler handler) throws InterruptedException {
            if (name2ctx.isEmpty()) {
                init(name, handler);
            } else {
                checkDuplicateName(name);
                DefaultChannelHandlerContext oldTail = tail;
                DefaultChannelHandlerContext newTail = new DefaultChannelHandlerContext(oldTail, null, name, handler); // 管道处理器上下文

                callBeforeAdd(newTail);

                oldTail.next = newTail;
                tail = newTail;
                name2ctx.put(name, newTail);

                callAfterAdd(newTail);
            }
        }

        private void checkDuplicateName(String name) {
            if (name2ctx.containsKey(name)) {
                throw new IllegalArgumentException("Duplicate handler name: " + name);
            }
        }

        private void init(String name, ChannelHandler handler) {
            DefaultChannelHandlerContext ctx = new DefaultChannelHandlerContext(null, null, name, handler);
            callBeforeAdd(ctx);
            head = tail = ctx;
            name2ctx.clear();
            name2ctx.put(name, ctx);
            callAfterAdd(ctx);
        }

        private static void callBeforeAdd(DefaultChannelHandlerContext ctx) {

        }

        private void callAfterAdd(DefaultChannelHandlerContext ctx) {

        }

        public void sendUpstream(ChannelEvent e) {
            DefaultChannelHandlerContext head = getActualUpstreamContext(this.head); // “管道处理器”上下文(可以处理Upstream)
            if (head == null) {
                System.out.println("The pipeline contains no upstream handlers; discarding: " + e);
                return;
            }

            sendUpstream(head, e);
        }

        void sendUpstream(DefaultChannelHandlerContext ctx, ChannelEvent e) {
            try {
                ((ChannelUpstreamHandler) ctx.getHandler()).handleUpstream(ctx, e); // 通知管道处理器
            } catch (Throwable t) {
                t.printStackTrace();
            }
        }

        public void sendDownstream(ChannelEvent e) {
            DefaultChannelHandlerContext tail = getActualDownstreamContext(this.tail);
            if (tail == null) {
                try {
                    getSink().eventSunk(this, e);
                    return;
                } catch (Throwable t) {
                    t.printStackTrace();
                    return;
                }
            }

            sendDownstream(tail, e); // 触发“handleDownstream”是事件
        }

        void sendDownstream(DefaultChannelHandlerContext ctx, ChannelEvent e) {
            if (e instanceof UpstreamMessageEvent) {
                throw new IllegalArgumentException("cannot send an upstream event to downstream");
            }

            try {
                ((ChannelDownstreamHandler) ctx.getHandler()).handleDownstream(ctx, e);
            } catch (Throwable t) {
                t.printStackTrace();
            }
        }

        private DefaultChannelHandlerContext getActualUpstreamContext(DefaultChannelHandlerContext ctx) {
            if (ctx == null) {
                return null;
            }

            DefaultChannelHandlerContext realCtx = ctx;
            while (!realCtx.canHandleUpstream()) {  // 不可以处理Upstream
                realCtx = realCtx.next; // 获取下一个
                if (realCtx == null) {
                    return null;
                }
            }

            return realCtx;
        }

        private DefaultChannelHandlerContext getActualDownstreamContext(DefaultChannelHandlerContext ctx) {
            if (ctx == null) {
                return null;
            }

            DefaultChannelHandlerContext realCtx = ctx;
            while (!realCtx.canHandleDownstream()) { // 不可以处理Downstream
                realCtx = realCtx.prev;
                if (realCtx == null) {
                    return null;
                }
            }

            return realCtx;
        }

        /**
         * 处理器上下文
         */
        private final class DefaultChannelHandlerContext implements ChannelHandlerContext {
            volatile DefaultChannelHandlerContext next;
            volatile DefaultChannelHandlerContext prev;
            private String name;
            private ChannelHandler handler;
            private final boolean canHandleUpstream;
            private final boolean canHandleDownstream;

            public DefaultChannelHandlerContext(DefaultChannelHandlerContext prev, DefaultChannelHandlerContext next, String name, ChannelHandler handler) {
                if (name == null) {
                    throw new NullPointerException("name");
                }

                if (handler == null) {
                    throw new NullPointerException("handler");
                }

                canHandleUpstream = handler instanceof ChannelUpstreamHandler;
                canHandleDownstream = handler instanceof ChannelDownstreamHandler;

                this.prev = prev;
                this.next = next;
                this.name = name;
                this.handler = handler;
            }

            public String getName() {
                return name;
            }

            public void setName(String name) {
                this.name = name;
            }

            public ChannelHandler getHandler() {
                return handler;
            }

            public void setHandler(ChannelHandler handler) {
                this.handler = handler;
            }

            public boolean canHandleDownstream() {
                return canHandleDownstream;
            }

            public boolean canHandleUpstream() {
                return canHandleUpstream;
            }

            public void sendDownstream(ChannelEvent e) {
                DefaultChannelHandlerContext prev = getActualDownstreamContext(this.prev);
                if (prev == null) {
                    try {
                        getSink().eventSunk(DefaultChannelPipeline.this, e); // 发送数据给 sink
                    } catch (Throwable t) {
                        t.printStackTrace();
                    }
                } else {
                    DefaultChannelPipeline.this.sendDownstream(prev, e);
                }
            }

            public void sendUpstream(ChannelEvent e) {
                DefaultChannelHandlerContext next = getActualUpstreamContext(this.next);
                if (next != null) {
                    DefaultChannelPipeline.this.sendUpstream(next, e);
                }
            }
        }

        private static final class DiscardingChannelSink implements ChannelSink {
            DiscardingChannelSink() {
            }

            public void eventSunk(ChannelPipeline pipeline, ChannelEvent e) {
                System.out.println("Not attached yet; discarding: " + e);
            }

            public void exceptionCaught(ChannelPipeline pipeline,
                                        ChannelEvent e, Exception cause) throws Exception {
                throw cause;
            }
        }
    }


}

输出

hello, this is class cn.java.netty3_6_6.internal.pipeline.DefaultChannelPipelineTest$FooOneChannelUpstreamHandler
hello, this is class cn.java.netty3_6_6.internal.pipeline.DefaultChannelPipelineTest$FooTwoChannelUpstreamHandler

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值