pushlet源码分析

服务器端
SessionManager: session管理者,创建session,保存了当前所有活动着的session

  • 超时订时钟定时扫锚超时的session,将其停止掉
  • session在每次请求时会更新一下lease time,超时时根据这个时间来判断,如果客户端长期不处于活跃状态就会被杀掉
    Subscriber:订阅者
  • 每个session会对应一个subscriber
  • 内部实现了一个queue,有事件时产生时,Dispatcher会通知给Subscriber
  • 客户过来拉数据时,会从这个queue里取出数据push给客户端。
    Dispatcher:消息分发者,有新消息到来时,会分发给所有subscriber.

public class Session implements Protocol, ConfigDefs {
private Controller controller ;
private Subscriber subscriber ;
}
pushlet支持三种模式:
stream:采用长连接的方式,服务器会占用servelt线程不会释放,有数据时就会主动推给客户端。
poll:服务端轮询
pull:服务拉,感觉跟poll一样,都是用ajax定时器
下面是Dispatcher里的代码,在这里分别对三种不同的模式在服务器端进行了不同处理
public void fetchEvents (Command aCommand) throws PushletException {
Event[] events = null;
// 采用长连接方式,将事件推给客户端
// 采用while死循环方式
// 对于poll和pull在没有数据里会从循环中跳出来
// stream会被阻塞
long eventSeqNr = 1;

           while (isActive()) {
                  // Indicate we are still alive
                  lastAlive = Sys.now();
                  // Update session time to live
                  session.kick();
                  //取下一个事件,stream模式没有数据将会阻赛,对拉模式将会直接返加回,返回代码在for之后
                  try {
                        // Put heartbeat in queue when starting to listen in stream mode
                        // This speeds up the return of *_LISTEN_ACK
                        if (mode .equals(MODE_STREAM) && eventSeqNr == 1) {
                               eventQueue.enQueue(new Event(E_HEARTBEAT));
                       }
                       events = eventQueue.deQueueAll(queueReadTimeoutMillis );
                 } catch (InterruptedException ie) {
                       warn( "interrupted");
                       bailout();
                 }
                  // Send heartbeat when no events received
                 .......................
                 ......省略代码.........
                 .......................
                  for (int i = 0; i < events.length; i++) {
                       .......................
                       .........省略代码.......
                       .......................
                        // 将事件推到客户端
                        try {
                               // Set sequence number
                              events[i].setField( P_SEQ, eventSeqNr++);
                               // Push to client through client adapter
                              clientAdapter.push(events[i]);
                       } catch (Throwable t) {
                              bailout();
                               return;
                       }
                 }
                  // 拉模式和轮洵模式,数据推完了之后直接跳出,释放servlet线程,返回,这与stream模式不一样
                  if (mode .equals(MODE_PULL) || mode.equals( MODE_POLL)) {
                       sendRefresh(clientAdapter, refreshURL);
                        // Always leave loop in pull/poll mode
                        break;
                 }
          }
   }

客户端
客户端基本上采用两种方式:iframe和ajax
iframe方式:poll,pull采用timeout方式来保持与服务器的会话,stream是长连接所以iframe会一直处于取数据状态,有可能浏览器会一直转圈
ajax方式:同上,基本原理差不多,只是ajax的可以异步方式来取数据。对于stream方式需要浏览器支持readyState=3,IE不支持
缺陷
基本上pushlet只能适应小型应用,对于大型应用很容易出现性能问题,长连接保存方式采用hold线程方式,很容易把服务器的servelet线程全用完,导至不能接收新的请求,所以这里要采用nio的方式来做,异步化。而且在分发事件,mach的方式采用遍历的方式,性能上也有问题,可以采用消息订阅的方式来解决。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值