Pushlet工作流程分析时采用从前台页面请求到后台程序响应,后台程序执行流程,最后前台对响应请求。分析对象是ajax-pushlet-client客户端。分析工具借助了firebug。
1)页面加载时,调用PL._addEvent(window, 'load', PL._init, false),其本质是调用了window.οnlοad=PL._init(),即获取XMLHttpRequest对象,设定pushlet的请求URL为pushlet.srv,将状态置为STATE_READY。
2)通过某种方式调用了joinListen(aSubject),加入、监听、并订阅(subscribe),这里的aSubject和subscrible是“/pushlet/ping”,构造好query,然后调用PL._doRequest('join-listen', query),这时的query是值为“p_format=xml-strict&p_mode=pull&p_subject=/pushlet/ping”。参数含义:
p_format:响应格式,这里指严格的xml;
p_mode:pushlet模式;
p_subject:请求主题。
3)是否等待状态准备好(waitForState)为false,即可以直接进行请求,其原因是在初始化时已将状态设置为STATE_READY了,向服务器端发出请求,利用GET请求,URL为“../../pushlet.srv?p_event=join-listen&p_format=xml-strict&p_mode=pull&p_subject=/pushlet/ping”。参数补充说明:p_event,即请求事件类型,这里为“join-listen”;而pushlet.srv是pushlet servlet配置地址,在web.xml中指明。
4)第一次以GET方式请求:
GET 方式请求:
eventType=join-listen
p_subject=/pushlet/ping
p_format=xml-strict
p_mode=pull
p_event=join-listen
创建一个Session 设置userAgent=Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.0.10) Gecko/2009042316 Firefox/3.0.10
创建一个Command实例:包括一个Session,事件Event,HTTP Servlet请求,HTTP Servlet响应
处理来自客户端的servlet请求
不同事件决定不同的操作
先请求加入
加入操作
Pushlet[INFO] SessionManager: Sun Jun 14 20:48:55 CST 2009 sapeledowe at 127.0.0.1 added
取得返回格式,默认值为js
实际值为xml-strict
新建响应事件,类型为join-ack
响应事件P_ID=sapeledowe
响应事件P_FORMAT=xml-strict
Pushlet[INFO] S-127.0.0.1[sapeledowe]: [Controller] joined
如果返回事件不是nack,再请求监听
请求监听操作
获取一个订阅者,设置主题=/pushlet/ping 标签=null
Pushlet[INFO] S-127.0.0.1[sapeledowe]: [Subscriber] Subscription added subject=/pushlet/ping sid=vusos label=null
Pushlet[INFO] S-127.0.0.1[sapeledowe]: [Controller] Listening mode=pull userAgent=mozilla/5.0 (windows; u; windows nt 5.1; zh-cn; rv:1.9.0.10) gecko/2009042316 firefox/3.0.10
如果监听返回事件不是nack,则设置响应事件类型为join-listen-ack
响应事件类型为listen 或者 refresh
获得订阅者
从队列中获取事件,并推送至客户端
设置响应URL=/blchat/pushlet.srv?p_id=sapeledowe&p_event=refresh
发送 刷新事件 到客户端
设置响应事件的属性
通过客户端适配器推送给客户端
响应事件:
p_event=join-listen-ack
p_mode=pull
p_time=1244995572
p_id=sebocegebi
p_format=xml-strict
p_sid=nehon
p_event=refresh
p_time=1244995572
p_wait=5888
p_url=/blchat/pushlet.srv?p_id=sebocegebi&p_event=refresh
第二次请求:
GET 方式 eventType=refresh
p_id=sapeledowe
p_event=refresh
创建一个Command实例:包括一个Session,事件Event,HTTP Servlet请求,HTTP Servlet响应
处理来自客户端的servlet请求
不同事件决定不同的操作
响应事件类型为listen 或者 refresh
获得订阅者
从队列中获取事件,并推送至客户端
设置响应URL=/blchat/pushlet.srv?p_id=sapeledowe&p_event=refresh
发送 刷新事件 到客户端
设置响应事件的属性
通过客户端适配器推送给客户端
结论:
1、第一次请求后建立一个服务器端长久的session,同时创建一个对应的subscribe一个controller,并将他们与session关联。
2、系统中Event是怎么产生的:系统中产生的EVENT是来源于系统自带的几个产生线程。TestEventPullSources中有几个静态内部内,它们在系统初始化的时候就自动创建了。系统通过Dispatcher类将事件分发到各个Session工厂中各个Session中,分别加入到各自的Subscribe的EventQueue中去。
3、servlet取得reflesh操作请求后重新读取队列中的事件,然后将其转换为XML输出到前台,最后再输出一个“reflesh”事件。响应事件对应了JavaScript里相应的对象。“reflesh”事件导致再次请求服务器,不过这一次不再创建session,而是根据sessionId直接取得服务器端实例,然后再获取事件队列中的事件,如此循环。
5、退出时,停止session,移去所有的subscriptions,设置响应事件为“E_LEAVE_ACK”,并将其作为控制类事件发送到客户端。
后面将对Pushlet源代码中的设计模式和二次开发过程进行分析。