Dict.CN 在線詞典, 英語(yǔ)學(xué)習(xí), 在線翻譯

          都市淘沙者

          荔枝FM Everyone can be host

          統(tǒng)計(jì)

          留言簿(23)

          積分與排名

          優(yōu)秀學(xué)習(xí)網(wǎng)站

          友情連接

          閱讀排行榜

          評(píng)論排行榜

          使用xmlhttp和Java session監(jiān)聽(tīng)改善站內(nèi)消息系統(tǒng)

          ??這個(gè)題目含有許多需要解釋的概念,最容易說(shuō)明的是“站內(nèi)消息”,這是很多論壇都有的功能,可以通過(guò)web向其他的在線用戶(hù)發(fā)送消息,很多用戶(hù)都使用過(guò)。站內(nèi)消息的第一個(gè)好處是大家都不需要安裝客戶(hù)端,你不用知道對(duì)方的MSN或者QQ,就能與他聯(lián)系,稱(chēng)贊他的觀點(diǎn)或者是給他一頓臭罵。第二個(gè)好處是客戶(hù)管理方便,利用session來(lái)維護(hù)在線名單,各種腳本都已經(jīng)把session操作封裝得很易用了,不用像其他無(wú)狀態(tài)的即時(shí)通信工具(比如使用UDP通信的工具)一樣,要費(fèi)一些腦細(xì)胞來(lái)解決在線名單的問(wèn)題。缺點(diǎn)嘛,就是實(shí)時(shí)性不好,一般是在用戶(hù)跳轉(zhuǎn)或者刷新頁(yè)面才能探測(cè)消息、更新在線名單。

             Session監(jiān)聽(tīng)嘛,沒(méi)什么好解釋的,java提供了很靈活的事件機(jī)制來(lái)監(jiān)聽(tīng)session,可以監(jiān)聽(tīng)session的創(chuàng)建和銷(xiāo)毀,監(jiān)控session所攜帶數(shù)據(jù)的創(chuàng)建、變化和銷(xiāo)毀,可以監(jiān)聽(tīng)session的銳化和鈍化(了解對(duì)象序列化的兄弟應(yīng)該知道這個(gè)),其他的平臺(tái)是個(gè)什么情況我不太清楚,估計(jì)也差不多吧。如果能夠?qū)λ锌蛻?hù)的session進(jìn)行監(jiān)控,就不用再去操作麻煩而危險(xiǎn)的Application了。

                Xmlhttp是MS推的一項(xiàng)技術(shù),功能很復(fù)雜,可以做很多事情,比如客戶(hù)端可以在簡(jiǎn)單的HTML中打開(kāi)HTTP連接,主動(dòng)向server請(qǐng)求數(shù)據(jù)并獲得返回?cái)?shù)據(jù),是DOM技術(shù)一個(gè)非常重要的應(yīng)用,利用它來(lái)寫(xiě)無(wú)刷新的動(dòng)態(tài)頁(yè)面簡(jiǎn)直是so?easy,做過(guò)web開(kāi)發(fā)的兄弟應(yīng)該明白它的意義有多么重大。

          一、?session監(jiān)聽(tīng)

             servlet中對(duì)session的監(jiān)聽(tīng)有很多接口,功能很靈活,最常用的是監(jiān)聽(tīng)Session和Attribute。這里要澄清一下概念,servlet中的session監(jiān)聽(tīng)和Attribute監(jiān)聽(tīng)含義有差別,session監(jiān)聽(tīng)指的不是我們一般所理解的放置一個(gè)session或者銷(xiāo)毀一個(gè)session,這是Attribute監(jiān)聽(tīng)的功能,因?yàn)閟ervlet中放置session的語(yǔ)法是session.setAttribute(“session名”,要放入的對(duì)象)。而session監(jiān)聽(tīng),監(jiān)聽(tīng)的是HTTP連接,只要有用戶(hù)與server連接,就算連接的是一個(gè)空白的jsp頁(yè)面,也會(huì)觸發(fā)session事件,所以此處的session實(shí)際上指的是connection,用來(lái)統(tǒng)計(jì)當(dāng)前在線用戶(hù)數(shù)最合適了。不知道我說(shuō)清楚了沒(méi)有。下面分別講解這兩種監(jiān)聽(tīng)方式。

          1、?session監(jiān)聽(tīng)

             首先編寫(xiě)一個(gè)session監(jiān)聽(tīng)類(lèi),實(shí)作HttpSessionListener接口,它的作用是計(jì)算當(dāng)前有多少個(gè)在線用戶(hù):

          1. /**
          2. *@Author?bromon
          3. *2004-6-12
          4. */
          5. package?org.bromon.test;
          6. import?javax.servlet.*;
          7. import?javax.servlet.http.*;
          8. public?class?SessionCount?implements?HttpSessionListener
          9. {
          10. ????private?static?int?count=0;
          11. ????public?void?sessionCreated(HttpSessionEvent?se)
          12. ????{
          13. ????????count++;
          14. ????????System.out.println(“session創(chuàng)建:”+new?java.util.Date());
          15. ????}
          16. ????public?void?sessionDestroyed(HttpSessionEvent?se)
          17. ????{
          18. ???????count--;
          19. ???????System.out.println(“session銷(xiāo)毀:”+new?java.util.Date());
          20. ????}
          21. ????public?static?int?getCount()
          22. ????{
          23. ???????return(count);
          24. ?????}
          25. }



             怎么樣,是不是一目了然?count被定義為static,是因?yàn)橐WC整個(gè)系統(tǒng)只有這一個(gè)count。如果你實(shí)在不放心,可以把它寫(xiě)成一個(gè)單例類(lèi)。

             然后在web.xml中聲明這個(gè)監(jiān)聽(tīng)器:
          <listener>
          <listener-class>
          org.bromon.test.SessionCount
          </listener-class>
          </listener>

             編寫(xiě)一個(gè)測(cè)試頁(yè)面test.jsp,內(nèi)容是獲得count:
          <%
          int?count=org.bromon.test.SessionCount.getCount();
          out.println(count);
          %>

             需要注意的是,這里根本不涉及任何session的操作。重啟動(dòng)App?server,試著連接test.jsp,可以看到監(jiān)聽(tīng)器已經(jīng)開(kāi)始工作。

          2、?Attribute監(jiān)聽(tīng)
             作為一個(gè)站內(nèi)消息系統(tǒng),肯定要獲得所有登陸者的ID,才有可能互發(fā)消息。這就涉及Attribute監(jiān)聽(tīng)。假設(shè)我們寫(xiě)了個(gè)用戶(hù)登陸的模塊,用戶(hù)通過(guò)身份驗(yàn)證之后會(huì)產(chǎn)生一個(gè)session,保存它的相關(guān)信息,比如:
          1. //check.jsp
          2. <%
          3. ????String?name=request.getParameter(“name”);
          4. ????Name=new?String(name.getBytes(“ISO8859-1”));
          5. ????session.setAttribute(“user”,name);
          6. %>


             做過(guò)jsp的兄弟應(yīng)該對(duì)這段代碼再熟悉不過(guò)了,下面寫(xiě)個(gè)監(jiān)聽(tīng)器來(lái)監(jiān)聽(tīng)用戶(hù)登陸,把所有用戶(hù)的ID保存到一個(gè)List當(dāng)中,這個(gè)監(jiān)聽(tīng)器實(shí)作HttpSessionAttributeListener接口:

          1. /**
          2. *@Author?bromon
          3. *2004-6-12
          4. */
          5. package?org.bromon.test;
          6. import?javax.servlet.*;
          7. import?javax.servlet.http.*;
          8. import?java.util.*;
          9. public?class?OnlineList?implements?HttpSessionAttributeListener
          10. {
          11. ????private?static?List?list=new?ArrayList();
          12. ????public?void?attributeAdded(HttpSessionBindingEvent?se)
          13. ????{
          14. ????????if(“user”.equals(se.getName()))
          15. ????????{
          16. ????????????list.add(se.getValue());
          17. ?????????}
          18. ????}
          19. ????public?void?attributeRemoved(HttpSessionBindingEvent?se)
          20. ????{
          21. ?????????if(“user”.equals(se.getName()))
          22. ?????????{
          23. ????????????list.remove(se.getValue());
          24. ?????????}
          25. ????}
          26. ????public?void?attributeReplaced(HttpSessionBindingEvent?se){}
          27. ????public?static?List?getList()
          28. ????{
          29. ?????????return(list);
          30. ?????}
          31. }


          寫(xiě)個(gè)簡(jiǎn)單的jsp來(lái)得到用戶(hù)列表:
          <%
          ????java.util.List?list=org.bromon.test.OnlineList.getList();
          ????out.println(“共有”+list.size()+”名用戶(hù)已登陸:”);
          ????for(int?I=0;I<lise.size();i++)
          ????{
          ????????out.println(list.get(i));
          ????}
          %>

          也許你說(shuō),這有什么神奇呢,監(jiān)聽(tīng)session而已,不著急,看看xmlhttp。

          二、?XMLHTTP

             XMLHTTP的用處很多,這里只說(shuō)我們需要的,就是無(wú)刷新的與server通信,看這段代碼:

          1. <script?language="javascript">?
          2. xml?=?new?ActiveXObject("Microsoft.XMLHTTP");?
          3. var?post="?";//構(gòu)造要攜帶的數(shù)據(jù)?
          4. xml.open("POST","http://localhost:7001/TestWL/index.jsp",false);//使用POST方法打開(kāi)一個(gè)到服務(wù)器的連接?
          5. xml.setrequestheader("content-length",post.length);?
          6. xml.setrequestheader("content-type","application/x-www-form-urlencoded");?
          7. xml.send(post);//發(fā)送數(shù)據(jù)?
          8. var?res?=?xml.responseText;//接收服務(wù)器返回的數(shù)據(jù)?
          9. document.write(res);?
          10. </script>



             豁然開(kāi)朗,這段代碼就是打開(kāi)一個(gè)HTTP連接,以標(biāo)準(zhǔn)的HTTP格式傳遞數(shù)據(jù),如果你喜歡,可以用XML的格式來(lái)傳遞。更改一下xml對(duì)象的構(gòu)造方式就可以兼容Mozilla和Netscape。下面來(lái)寫(xiě)一個(gè)輪詢(xún),每隔一段時(shí)間刷新一次用戶(hù)列表,當(dāng)然,是不需要刷新頁(yè)面的:

          1. <html>
          2. <head><title>探測(cè)器</title>
          3. <script?language="javascript">
          4. function?detect()
          5. {
          6. xml?=?new?ActiveXObject("Microsoft.XMLHTTP");?
          7. var?post="?";//構(gòu)造要攜帶的數(shù)據(jù)?
          8. xml.open("POST","http://localhost:7001/TestWL/index.jsp",false);//使用POST方法打開(kāi)一個(gè)到服務(wù)器的連接,以異步方式通信?
          9. xml.setrequestheader("content-length",post.length);?
          10. xml.setrequestheader("content-type","application/x-www-form-urlencoded");?
          11. xml.send(post);//發(fā)送數(shù)據(jù)?
          12. var?res?=?xml.responseText;//接收服務(wù)器返回的數(shù)據(jù)?
          13. list.innerText=res;
          14. setTimeout(“detect()”,5000);//每隔5秒鐘輪詢(xún)一次
          15. }?
          16. </script>
          17. <body?onload=”detect()”>
          18. <a?id=”list”></a>
          19. </body>
          20. </html>


             這樣的通信方式數(shù)據(jù)量很小,不用重新傳遞整個(gè)頁(yè)面,5秒鐘輪一次,普通PC也能承受較大的在線數(shù)。構(gòu)造一個(gè)探測(cè)器來(lái)監(jiān)聽(tīng)在線列表和消息,效果是很好的,即使你的客戶(hù)坐在電腦前袖手旁觀,鍵鼠都不碰一下,也能保證數(shù)據(jù)即時(shí)傳遞,頁(yè)面也不會(huì)發(fā)生跳轉(zhuǎn)和刷新。

             Session監(jiān)聽(tīng)加上XMLHTTP通信,開(kāi)發(fā)一個(gè)較為完善的站內(nèi)消息系統(tǒng)實(shí)在易如反掌。

          posted on 2006-04-26 15:35 都市淘沙者 閱讀(698) 評(píng)論(0)  編輯  收藏 所屬分類(lèi): AJAX/XML/ANT/SOAP/WEBService

          主站蜘蛛池模板: 关岭| 安丘市| 繁峙县| 历史| 平南县| 依安县| 乐昌市| 金山区| 北票市| 文化| 沛县| 桐乡市| 浙江省| 景德镇市| 巨鹿县| 沭阳县| 哈尔滨市| 日照市| 肇庆市| 安远县| 太和县| 辽阳市| 新晃| 冕宁县| 英山县| 诸暨市| 神木县| 遵义市| 宜黄县| 斗六市| 浦北县| 军事| 象州县| 巴彦淖尔市| 青田县| 竹山县| 廉江市| 黑水县| 杂多县| 珠海市| 遵义市|