高软作业3:观察者模式在Netty里面的应用

1.Netty的简单介绍

  ① Netty是基于Java NIO的网络应用框架,client-server框架

  ② Netty是一个高性能、异步事件驱动的NIO框架,它提供了对TCP、UDP和文件传输的支持,作为一个异步NIO框架,Netty的所有IO操作都是异步非阻塞的,通过FutureListener机制,用户可以方便的主动获取或者通过通知机制获得IO操作结果。

  ③ 作为当前最流行的NIO框架,Netty在互联网领域、大数据分布式计算领域、游戏行业、通信行业等获得了广泛的应用。

2.Netty中的观察者模式

  (1)经典的“观察者模式”模型图

  (2)netty版本:5.0.0(github)

<dependency>
	<groupId>io.netty</groupId>
	<artifactId>netty-all</artifactId>
	<version>5.0.0.Alpha2</version>
</dependency>

  (3)代码举例

 1   public void nettyTest(NioSocketChannel channel, Object object) {
 2         //新建被观察者
 3         ChannelFuture channelFuture = channel.writeAndFlush(object);
 4         //添加观察者一
 5         channelFuture.addListener(future -> {
 6             if (future.isSuccess()) {
 7  
 8             } else {
 9  
10             }
11         });
12         //添加观察者二
13         channelFuture.addListener(future -> {
14             if (future.isSuccess()) {
15  
16             } else {
17  
18             }
19         });
20     }

   (4)创建被观察者

1     @Override
2     public ChannelFuture writeAndFlush(Object msg) {
3         return writeAndFlush(msg, newPromise());
4     }
5 
6     @Override
7     public ChannelPromise newPromise() {
8         return new DefaultChannelPromise(channel(), executor());
9     }

 追溯上述例子中的源代码,发现 writeAndFlush() 最终返回的是一个 ChannelPromise 的对象,即被观察者。

  (5)添加观察者

 1     synchronized (this) {
 2             if (!isDone()) {
 3                 if (listeners == null) {
 4                     listeners = listener;
 5                 } else {
 6                     if (listeners instanceof DefaultFutureListeners) {
 7                         ((DefaultFutureListeners) listeners).add(listener);
 8                     } else {
 9                         final GenericFutureListener<? extends Future<V>> firstListener =
10                                 (GenericFutureListener<? extends Future<V>>) listeners;
11                         listeners = new DefaultFutureListeners(firstListener, listener);
12                     }
13                 }
14                 return this;
15             }
16         }

 跟踪 addListener() 方法,在DefaultPromise类里面发现这样上述代码

  public void add(GenericFutureListener<? extends Future<?>> l) {
        GenericFutureListener<? extends Future<?>>[] listeners = this.listeners;
        final int size = this.size;
        if (size == listeners.length) {
            this.listeners = listeners = Arrays.copyOf(listeners, size << 1);
        }
        listeners[size] = l;
        this.size = size + 1;

        if (l instanceof GenericProgressiveFutureListener) {
            progressiveSize ++;
        }
    }

点击 add() 方法,发现多个listener被封装成一个GenericFutureListener数组,也就是多个观察者

   (6)如何通知

  @Override
    public boolean trySuccess(V result) {
        if (setSuccess0(result)) {
            notifyListeners();
            return true;
        }
        return false;
    }

  ......

  try {
            l.operationComplete(future);
        } catch (Throwable t) {
            logger.warn("An exception was thrown by " + l.getClass().getName() + ".operationComplete()", t);
        }

同样的,在 writeAndFlush() 方法的跟踪过程中,分别有 notifyListeners() 方法和 operationComplete() 方法,实现通知观察者的功能,完成异步流程。

3.总结:

netty通过Promise模式或者说ChannelFuture模式实现了观察者模式。netty通过实现观察者模式达到异步通知,每次写成功写失败,都会回调给listener,也就是回调到future.isSuccess()等方法。其实就是变种的观察者模式。

优点:在netty中使用观察者模式,可以充分利用NioEventLoopGroup这一线程池的资源,避免启动线程阻塞在网络链接上。

4.参考文献

①Netty writeAndFlush() 流程与异步

②Netty4之Future/Promise异步模型

③netty设计模式-观察者模式

④netty源码分析之writeAndFlush全解析

猜你喜欢

转载自www.cnblogs.com/txmjh/p/9826186.html