在上次关于AF框架的事件模型的随笔中介绍了AF的事件分发机制,这个事件分发机制比较好的解决了如果通过Web Services来让客户端得到服务器端事件的问题,让Web Service和Remoting的事件处理模型看上去完全一致,为在AF上开发事件驱动的应用程序带来极大的便捷。
但是由于这个模型在Web Service模式下是采用的轮询机制,这种机制会产生这样的问题:
- 性能问题。每个客户端都频繁的轮询服务器,在工作站比较多的情况下会给服务器的负载带来巨大的压力。
- 响应延迟。在这种事件分发机制下。事件的响应时延取决于轮询的频率,轮询频率越高则延迟越小,而频率越低则延迟越大。
这两个问题互相矛盾:为了提高事件的响应速度,就必须提高轮询频率;而提高了轮询频率又会加大服务器的负载。所以造成了事件响应速度和服务器负载两者不可兼得的局面。
为了解决这个问题,AF改良了事件分发机制,将事件探测器移到服务器端,结构如下图所示:
从结构上来看,没有太大的变化,主要的改变是将事件探测器从客户端移动到了服务器端。客户端照样也轮询事件,但是如果没有事件,服务器的这个线程就进入睡眠状态,不让它返回。同时该线程每隔一定时间就醒来检查一下有没有事件发生。如果有事件就马上返回。
因为这种轮询不占用网络资源,所以可以将服务器的轮询间隔时间设置得很短(目前默认值是100ms)。同时因为服务器Hold了线程,所以客户端的事件轮询也可以设置得很短,甚至可以无延迟。
这样一来,由于是服务器内部的线程处理,并且获取事件的操作代价并不高,所以这个事件探测器大部分时间都会是在休眠状态,因此服务器并没有被消耗多少资源。同时由于轮询不需要远程传递结果,因此可以将轮询时间设置得非常短,因此也极大的提高了事件的响应速度(原来的事件的最长响应时间是1s,现在是100ms,提高了十倍)。
另外,为了防止客户端意外的中断和请求超时,可以设置一个最长轮询次数。假如超过了最长轮询次数,服务器线程也返回,假如客户端仍然是活跃的,它马上会发出一个新的获取事件请求。然后服务器又开始进入新的轮询。