Twitteræ¡æ¶å¦ä¹ äºHttpé¿è¿æ¥ææ¯å®ç°server端pushåè½-Cometçç论ä¸å®æ
Cometç®ä»
å¨å¦ä¹ Twitterçæ¶æä¸ï¼åç°ä»ä»¬å¹¿æ³ä½¿ç¨äºCometææ¯ï¼åºäºHttpé¿è¿æ¥çæå¡å¨Pushææ¯ï¼Twitteræ¬èº«å¯¹äºæ°æ®çå®æ¶æ§è¦æ±è¾é«ï¼å æ¤ï¼éç¨Cometææ¯å¯ä»¥å¾å¥½å°è§£å³ä»ä»¬çé®é¢ã
Comet æ¯ä¸ç§æ°ç Web åºç¨æ¶æãåºäºè¿ç§æ¶æå¼åçåºç¨ä¸ï¼æå¡å¨ç«¯ä¼ä¸»å¨ä»¥å¼æ¥çæ¹å¼å客æ·ç«¯ç¨åºæ¨éæ°æ®ï¼èä¸éè¦å®¢æ·ç«¯æ¾å¼çååºè¯·æ±ãComet æ¶æé常éåäºä»¶é©±å¨ç Web åºç¨ï¼ä»¥å对交äºæ§åå®æ¶æ§è¦æ±å¾å¼ºçåºç¨ï¼å¦è¡ç¥¨äº¤æè¡æ åæãè天室å Web çå¨çº¿æ¸¸æçã
3.åºäºCometææ¯çå¼æºé¡¹ç®Pushlet
ä¸é¢æ¯ç¬è ç¿»è¯çå ³äºPushlet项ç®çç½ç®ä¹¦çå 容,åæåºèªï¼http://www.pushlets.com/doc/whitepaper-all.html
3.1 Pushlet ç½ç®ä¹¦
PushLetsæ¯åºäºServletçServer端ç´æ¥pushæ°æ®å°æµè§å¨ç«¯çææ¯ï¼è¿ç§pushææ¯çå®ç°ä¸ä½¿ç¨ä»»ä½æ件ï¼Flashï¼æè Java Appletãå®å 许server端ç´æ¥update webç½é¡µã
å®ç°server端pushåè½é常éç¨Appletï¼Flashçææ¯ãè¿äºææ¯æ¯è¾å¤æä¹é¾äºå®ç°ï¼æé²ç«å¢éå¶ï¼èä¸éè¦å¦å¤çserverçå¼åå·¥ä½åç»´æ¤ã
Pushletsæ¯åºäºServletçï¼æ°æ®æ¯server端ç´æ¥pushå°æµè§å¨ç«¯çç½é¡µä¸ï¼è¿å°±å 许serverå¯ä»¥å®æ¶å°æ´æ°ç½é¡µçå 容ãæµè§å¨å®¢æ·ç«¯éç¨JavaScriptæè å¨æHTMLææ¯ï¼å¯ä»¥æ¯æåç§ä»¥ä¸çæµè§å¨ï¼å¦NS(NetScape)åIEãè¿ç§æºå¶æ¯ä½¿ç¨ä¸ä¸ªservletçHTTPè¿æ¥ï¼è¿ä¸ªè¿æ¥ä¼æ¿åä¸æ®µJS代ç ç»æµè§å¨ï¼æµè§å¨ç¶åæ§è¡è¿æ®µä»£ç ï¼ä»èå®ç°äºç½é¡µç«¯çæ°æ®å®æ¶æ´æ°ãéè¿ä¸ä¸ªéç¨çServletï¼Pushletï¼ï¼æµè§å¨å®¢æ·ç«¯å¯ä»¥è®¢é é£äºéè¦æ¶å°äºä»¶ç主é¢ãæ 论ä½æ¶ï¼server æ¨éä¸ä¸ªäºä»¶ï¼é£äºè®¢é äºç¸å ³ç主é¢ç客æ·ç«¯é½ä¼è¢«éç¥å°ãäºä»¶å¯¹è±¡ï¼Event Objectï¼å¯ä»¥ä»¥JavaScriptï¼DHTML clientsï¼ï¼åºååçJava对象ï¼JSONï¼æè XMLå½¢å¼è¿åã
3.2 Pushlet项ç®çåè¡·
è¿ç§æºå¶ä»æç§æä¹ä¸æ¥è¯´æ¯è½»é级çï¼å®å©ç¨äºserverçserverçè¿æ¥ç®¡çå¨å线ç¨è®¾å¤ï¼javax.servlet APIsåæ åçJavaç¹æ§ï¼å¦éè¿wait()ånotify()æºå¶å®ç°çç产æ¶è´¹æ¨¡åã
ä¹æå¦å¤ä¸ç§ç¨åºï¼éè¦è®¢é ä»server端ä¸ææ´æ°çå¨æå 容ãå¦è¡ç¥¨çfeedsï¼ç³»ç»çç¶æï¼å¤©æ°é¢æ¥åå ¶å®ççæ§ç¨åºãè¿äºé½éµä»è§å¯è 模å¼ï¼åå¸ã订é 模å¼ï¼ï¼ç±å®¢æ·ç«¯æ³¨å订é serverç主é¢ã
å½é¡µé¢è£ è½½åï¼æ们åºè¯¥å¦ä½éç¥æµè§å¨ç«¯ï¼æè æ们åºè¯¥æä¹åï¼å¦ææ们è¦å®ç°éæ©æ§çé¨åæ´æ°ï¼ä¾å¦è¡ç¥¨ç³»ç»ï¼é常åªéè¦æ´æ°ä¸ä¸ªitemå°±å¯ä»¥äºï¼
3.Server端éç¥æµè§å¨å®¢æ·ç«¯çå¯è¡æ§æ¹æ¡
å 让æ们åå®æ们æä¸ä¸ªJavaçweb serverï¼æ们è¦è®²server端çæ°æ®éç¥å®¢æ·ç«¯ï¼è¾¾å°è¿ä¸ªåè½æä¸ç§æ¹å¼ï¼
1ï¼polling
æç®åçæ¹æ¡æ¯é¡µé¢å®æ¶å·æ°ï¼å¨HTMLçMetaæ ç¾éå å ¥å®æ¶å·æ°å®ä¹ï¼ç½é¡µæ¯éæå®çæ¶é´é½ä¼éæ°å·æ°é¡µé¢ã
2ï¼Server端çCallback
3ï¼Messagingï¼MOMï¼
è¿ä¸ªæ¹æ¡æ¯ï¼appletä½ä¸ºclient端éè¿TCP/IPæè æ è¿æ¥çUDPæ¶æ¯è¿æ¥ï¼ä¸æ¶æ¯ä¸é´ä»¶è¿è¡äº¤äºãä½ å¯è½ä½¿ç¨ä¸ä¸ªæ¶æ¯ä¸é´ä»¶äº§åå¦IBusï¼MQSeriesï¼IBM)æè WebLogic Eventsï¼BEAï¼æè å¼åä½ èªå·±çèªå®ä¹æ¶æ¯ã
4) 讨论
ä¸é¢çæ¯ç§è§£å³æ¹æ¡å¨å¤ææ§ï¼å®å ¨ï¼æ§è½ï¼æ©å±æ§ï¼æµè§å¨Javaçå ¼å®¹æ§åéå¶å¦é²ç«å¢çéå¶å 个æ¹é¢é½æèªå·±çåèªçä¼ç¼ºç¹ãåªç§æ¯æä¼åçæ¹æ¡å¨å¾å¤§ç¨åº¦ä¸ä¾èµäºä½ çåºç¨ç¨åºçéæ±ãä¾å¦ï¼å½ç¨æ·éè¦ä¸ä¸ªç´æ¥çç¶æ交äºï¼ä¾å¦ç½æ¿ç¨åºï¼server端callbacksæè Messageææ¯é常éç¨äºè¿ç§åºæ¯ã
é¤äºä¸é¢ç解å³æ¹æ¡ï¼æå¼åäºä¸ç§ææ¯-è½»é级ï¼ç¦å®¢æ·ç«¯ï¼ä¸éè¦appletæè ä»»ä½æ件ï¼ç´æ¥åèæ¬åHTMLæ´åï¼ä½¿ç¨æ åçHTTPè¿æ¥å¯ä»¥é¨ç½²ï¼ä»ç论ä¸ï¼å¨æ¯æServletçserverä¸ãå½ç¶æè¿ä¸ªææ¯æ¹æ¡ä¸æ¯è¦å代ä¸é¢çæ¹æ¡ãæçæå¾æ¯ç»ä½ å¢å ä¸ç§æ°çéæ©ãåJavaæ¶æå¸æè å¼å人åï¼ä½ åºè¯¥æ衡并éæ©åªç§æ¹æ¡ææ¯æéåä½ çåºç¨ç¨åºã
4.Pushletåºç¡
ä»ä¹æ¯Pushletï¼ä»ä»¬æ¯å¦ä½å·¥ä½çï¼ä»åçæ¥çï¼Pushletsæ¯å¼å¸¸ç®åçãä¸é¢æå°å±ç¤ºè¿äºåºç¡ç¥è¯ï¼åæ¶ä¹ä¼é带ä¸äºä»£ç ï¼
1ï¼.HTTPæµ
PushletsåºäºHTTPæµï¼å®æ¯ä¸ç§è¿æ ·çææ¯ï¼å®ç»å¸¸åºç¨å¨å¤åªä½çæµè§ä¸ï¼ä¾å¦QuickTimeãå½æ°çæ°æ®Pushå°clientä¹åï¼è¿æ¥ä¿æå¼å¯ç¶æï¼èä¸æ¯å
³éç¶æã
2ï¼.Example 1
åºäºHTTPæµçåºæ¬ç论ï¼æ们å¯ä»¥æé ä¸ä¸ªJSPæ件ï¼å®å®æä¸æåéæ°çHTMLå
容ç»Client端ã
<HTML> <HEAD> <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> <META HTTP-EQUIV="Pragma" CONTENT="no-cache"> </HEAD> <BODY BGCOLOR="blue" TEXT="white"> <% int i = 1; try { while (true) { out.print("<h1>"+(i++)+"</h1>"); out.flush(); try { Thread.sleep(3000); } catch (InterruptedException e) { out.print("<h1>"+e+"</h1>"); } } } catch (Exception e) { out.print("<h1>"+e+"</h1>"); } %> </BODY> </HTML>
å¨å®ä¾é¡µé¢ä¸ç¹å»å®ä¾1ãè¿ä¸ªå®ä¾ä¸æ¯å¾æç¨ï¼å 为pushedçå 容éè¦ä¸ææ¯æ·»å å°pageä¸ï¼èæ们æ´å å欢å·æ°å®ã
3ï¼Example 2
è¿éæ们ç´æ¥è·³å°Pushletçå·¥ä½åçä¸ãå¨å®ä¾é¡µé¢ç¹å»example 2ï¼å¯ä»¥çå°è¿ä¸ªé¡µé¢æ¯æ¯3ç§å·æ°ä¸æ¬¡çï¼å°è¿éæ们已ç»å®æäºå·¥ä½äºåï¼
è¿ä¸ªå®ä¾å
å«äºä¸ä¸ªæä»¶ï¼ push-js-stream.html, push-js-stream-pusher.jsp å push-js-stream-display.htmlã
push-js-stream.html æ¯ä¸»é¡µé¢ï¼å¨HTML FRAMEéé¢å
å«å
¶å®ä¸¤ä¸ªé¡µé¢ï¼è®©æ们è·éäºä»¶ç路线æ
¢æ
¢çä¸å»ã
ä¸é¢è¿ä¸ªæ件å举äºpush-js-stream-pusher.jspçå
容ï¼è¿ä¸ªJSPæ件æ¯å½è¯·æ±å®æ¶ï¼å¨serverä¸æ§è¡çï¼è¿ä¸ªJSPç主ä½é¨å代ç å¦ä¸ï¼
7: <% 8: /** Start a line of JavaScript with a function call to parent frame. */ 9: String jsFunPre = "<script language=JavaScript >parent.push('"; 10: 11: /** End the line of JavaScript */ 12: String jsFunPost = "')</script> "; 13: 14: int i = 1; 15: try { 16: 17: // Every three seconds a line of JavaScript is pushed to the client 18: while (true) { 19: 20: // Push a line of JavaScript to the client 21: out.print(jsFunPre+"Page "+(i++)+jsFunPost); 22: out.flush(); 23: 24: // Sleep three secs 25: try { 26: Thread.sleep(3000); 27: } catch (InterruptedException e) { 28: // Let client display exception 29: out.print(jsFunPre+"InterruptedException: "+e+jsFunPost); 30: } 31: } 32: } catch (Exception e) { 33: // Let client display exception 34: out.print(jsFunPre+"Exception: "+e+jsFunPost); 35: } 36: %> è¿éæ们åçå°äºä¸ä¸ªå®æ¶å¾ªç¯ï¼æ¯3ç§éåæµè§å¨æå°äºä¸äºHTML代ç ãä½æ¯è¯·æ³¨æä¸ç¹ï¼è¿ä¸ªä¸æ¯push HTMLï¼èæ¯JavaScriptï¼è¿æ¯ä»ä¹ææï¼ å®pushäºä¸è¡åè¿æ ·çä¸è¡ä»£ç ï¼<script language=JavaScript >parent.push('Page 4')</script>ï¼è¿å¯¹äºæµè§å¨æ¯ä»ä¹ææå¢ï¼æµè§å¨æå®èªå·±è¿è¡çJavaScriptå¼æï¼ å®ä¼æ§è¡æ¯æ¬¡æ¥çæ°çJS代ç ãå®æ¯è°ç¨parent.push()çJavaScript代ç ãå½åçparentæ¯FrameçParentï¼å®æ¯æ 们åæ¥listç第ä¸ä¸ªæ件push-js-stream.htmlï¼æ们åççè¿éæä»ä¹ï¼
ä¸é¢ç代ç æ们å¯ä»¥çå°æå¡ç«¯Pushè¿æ¥çJavascript push()æ¹æ³å¨åªéå¾å°æ§è¡äºã
è¿å°±æ¯Pushletsçåºæ¬çåçï¼æ们åªæ¯ä»ä¸ä¸ªServlet stream è¥å¹²è¡JSãè¿äºJS被æµè§å¨è§£éæ§è¡ãè¿ä¸ªä¾å说æäºPushletçå·¥ä½æºå¶ï¼ä½æ¯ä»ç¶æå 个é®é¢éè¦è§£å³ã并ä¸éè¦æ·»å æ´å¤çfeatureãä»è¿ä¸ªåå æ¥è®²ï¼æå·²ç»buildäºä¸ä¸ªè½»é级çserver端çPushletæ¡æ¶(å¦ä¸é¢çç±»è§å¾æ示)ï¼å ä¸å 个客æ·ç«¯çJSç±»åºã
5.ä¸åªæ¯Java-å¨æHTML
DHTMLæçæ¯HTMLï¼CSSï¼JavaScriptåæµè§å¨DOMçèåãä¼ ç»æä¹ä¸æ¥è®²ï¼åªæéè¿ä»serveréæ°è£
è½½pageæè½æ¹åpageçå
容ï¼DHTMLå
许pageè£
è½½åä»ç¶è½å¤å®å
¨æ§å¶ä¸ä¸ªHTMLææ¡£ï¼ä½ ä¹è®¸å·²ç»çå°äºä¸äºwebä¸çå®ä¾å¦imageçæ»å¨ï¼å¼¹åºå
容åæå èåãDHTMLå¯ä»¥æ¯æ4ç§ç±»åçæµè§å¨ã
ä»ç¨åºåè§åº¦çï¼æµè§å¨çdomï¼ä¾å¦å®çframeï¼æ®µè½ï¼è¡¨ççé½ä»£è¡¨äºä¸ç§å±æ¬¡æ§ç对象模å-DOMãDHTMLå
许页é¢å·²ç»è£
è½½åè½å¤å®å
¨æ§å¶ä¸ä¸ªHTMLææ¡£ãéè¿JSï¼ä½ å¯ä»¥æä½DOMï¼å æ¤ä½ ä¹å¯ä»¥æ¹ådocumentçå
容åå¤è§ãä½ å¯ä»¥ä»è¿äºå
ç´ æåç¨æ·äºä»¶ï¼å¦é¼ æ moveï¼formçæ交ãä¾å¦é¼ æ æ»è¿ä¸ä¸ªå¾çä¼äº§çä¸ä¸ªmouse-overäºä»¶ãdocumentå
ç´ çè³å¯ä»¥è¾¾å°å¨ç»ææï¼è¿çèµ·æ¥å¾ä¸éï¼æ¯å§ï¼æ们åªæ¯éè¦çæDHTMLçæ åï¼ä½æ¯è°å®ä¹äºDHTMLçæ åï¼
6.æ¡æ¶ç设计
Pushletæ¡æ¶å
许clientä»server订é
主é¢ï¼clientä¼ç¸ç»§æ¶å°äºä»¶ãè¿ä¸ªæ¡æ¶çåºæ¬è®¾è®¡æ¨¡å¼æ¯åå¸-订é
模å¼ï¼ä¹ç§°ä½è§å¯è
模å¼ï¼å®æ¢æserverï¼åæclientçç»ä»¶ã
- å´ç»Pushletç±»è设计äºserver端çéå
- å¨DHTML客æ·ç«¯ä¸ºäºæ¥æ¶äºä»¶è设计äºå¯ä»¥éç¨ç客æ·ç«¯çJSç±»åº(pushlet.js)
- 为Java客æ·ç«¯æ¥æ¶äºä»¶è设计客æ·ç«¯çJavaç±»(JavaPushletClient.java and JavaPushletClientListener.java)
- 为æ¾ç¤ºDHTMLå±è设计çè·¨æµè§å¨çDHTMLå·¥å ·åº(layer.js, layer-grid.js, layer-region.js)
1ï¼. Server-side 类设计å¾ï¼ä¸é¢çå¾åªéç¨äº0.04çæ¬ï¼