詳解Tomcat如何實現(xiàn)Comet
Comet模式是一種服務(wù)器端推技術(shù),它的核心思想提供一種能讓當(dāng)服務(wù)器端往客戶端發(fā)送數(shù)據(jù)的方式。Comet模式為什么會出現(xiàn)?剛開始人們在客戶端通過不斷自動刷新整個頁面來更新數(shù)據(jù),后來覺得體驗不好又使用了AJAX不斷從客戶端輪詢服務(wù)器更新數(shù)據(jù),然后是使用Comet模式由服務(wù)器端通過長連接推數(shù)據(jù)。Comet模式能大大減少發(fā)送到服務(wù)器端的請求從而避免了很多開銷,而且它還具備更好的實時性。
如圖所示,客戶端發(fā)送一個請求到服務(wù)器,服務(wù)器接收了連接后一直保持住連接不關(guān)閉;接著客戶端發(fā)送一個操作報文告訴服務(wù)器需要做什么操作,服務(wù)器處理完事件1后會給客戶端響應(yīng),然后處理完事件2后又會給客戶端響應(yīng);然后客戶端繼續(xù)發(fā)送操作報文給服務(wù)器,服務(wù)器再進(jìn)行響應(yīng)。
一般Comet模式需要NIO配合,而在BIO中無法使用Comet模式。在Tomcat內(nèi)部集成Comet模式的思路也比較清晰,引入了一個CometProcessor接口,此接口只有一個event方法,具體接口代碼如下:
public interface CometProcessor extends Servlet{ public void event(CometEvent event) throws IOException, ServletException; }
而CometEvent則表示Comet相關(guān)的事件,它包含四BEGIN, READ, END, ERROR四個事件,分別表示:
① BEGIN,表示請求開始,此時客戶端連接已被接收。
② READ,表示可以讀取客戶端連接,你可以開始讀取數(shù)據(jù)了,讀取的過程不會阻塞。
③ END,表示請求結(jié)束,此時客戶端連接將被斷開。
④ ERROR,表示發(fā)生了IO異常,一般將會結(jié)束此次請求并且連接會被斷開。
下面看一個簡單的例子:
public class CometServlet extends HttpServlet implements CometProcessor { protected ArrayList connections = new ArrayList(); public void event(CometEvent event) throws IOException, ServletException { HttpServletRequest request = event.getHttpServletRequest(); HttpServletResponse response = event.getHttpServletResponse(); if (event.getEventType() == CometEvent.EventType.BEGIN) { synchronized (connections) { connections.add(response); } } else if (event.getEventType() == CometEvent.EventType.ERROR) { synchronized (connections) { connections.remove(response); } }else if (event.getEventType() == CometEvent.EventType.END) { synchronized (connections) { connections.remove(response); } } else if (event.getEventType() == CometEvent.EventType.READ) { InputStream is = request.getInputStream(); byte[] buf = new byte[512]; do { int n = is.read(buf); if (n > 0) { System.out.println(new String(buf, 0, n)); } else if (n < 0) { return; } } while (is.available() > 0); } } }
這個例子中只是簡單的客戶端連接都接收起來而不做任何處理,并將客戶端發(fā)送過來的數(shù)據(jù)輸出。很容易理解,在BEGIN事件中接收連接并把響應(yīng)對象假如到列表中,發(fā)送ERROR或END事件時則將響應(yīng)對象移除,當(dāng)READ事件時則讀取數(shù)據(jù)并輸出。
有了CometProcessor接口后,Tomcat內(nèi)部就可以識別Comet模式的Servlet了,我們知道Tomcat對請求的處理是管道模式的,所以在Wrapper容器的管道中判斷加載的Servlet是否繼承了CometProcessor,繼承則說明是Comet模式,則使用Comet方式處理。它的處理過程如圖,當(dāng)一個客戶端連接到來,被接收器接收后注冊到NioChannel隊列中,Poller組件不斷輪詢是否有NioChannel需要處理,如果有則調(diào)用前面實例化的Comet模式Servlet,這里主要用到CometProcessor接口的event方法,Poller會將對應(yīng)的請求對象、響應(yīng)對象和事件封裝成都CometEvent對象并傳入event方法。此時即執(zhí)行event方法的邏輯,完成對不同事件的處理,從而實現(xiàn)了Comet模式。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
詳解Windows下調(diào)整Tomcat啟動參數(shù)的實現(xiàn)方法
這篇文章主要介紹了詳解Windows下調(diào)整Tomcat啟動參數(shù)的實現(xiàn)方法的相關(guān)資料,希望通過本文大家能夠修改Tomcat啟動參數(shù)來實現(xiàn)自己想要的效果,需要的朋友可以參考下2017-09-09淺析Tomcat各種日志的關(guān)系與catalina.out文件的分割問題
這篇文章主要介紹了Tomcat各種日志的關(guān)系與catalina.out文件的分割,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-10-10學(xué)習(xí)javaweb如何配置Tomcat的熱啟動
學(xué)習(xí)javaweb的時候每次更改項目都需要重新部署項目,如此一來比較麻煩,使用tomcat的熱啟動就可以解決這個問題2014-09-09詳解用Tomcat服務(wù)器配置https雙向認(rèn)證過程實戰(zhàn)
本篇文章主要介紹了詳解用Tomcat服務(wù)器配置https雙向認(rèn)證過程實戰(zhàn),具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-05-05搭建Tomcat 8源碼開發(fā)環(huán)境的步驟詳解
相信大家都知道開源軟件tomcat目前幾乎已經(jīng)是Java web開發(fā)的必備軟件了,目前有很多關(guān)于tomcat的書籍,已經(jīng)通過配置對tomcat進(jìn)行一些跟應(yīng)用業(yè)務(wù)功能的調(diào)優(yōu),但感覺如果僅僅只是了解一些配置,可能稍微少了點什么,下面通過本文深入到源代碼中進(jìn)行學(xué)些和了解。2016-10-10關(guān)于Tomcat?結(jié)合Atomikos?實現(xiàn)JTA的方法
Tomcat作為一款經(jīng)典的Web服務(wù)器,在開發(fā)、測試和生產(chǎn)環(huán)境中得到了廣泛的使用。但Tomcat畢竟不是Java EE服務(wù)器,因此在EJB,JTA方面并沒有提供支持。本文講述了Tomcat使用Atomikos實現(xiàn)JTA的一種方法,需要的朋友可以參考下2021-11-11