国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
實戰(zhàn) Comet 應(yīng)用程序開發(fā)

使用 IBM Web 2.0 Feature Pack 和 Dojo 開發(fā)基于 Comet 架構(gòu)的應(yīng)用程序





級別: 中級

成 富 (chengfbj@cn.ibm.com), 軟件工程師, IBM 中國軟件開發(fā)中心

2008 年 7 月 15 日

Comet 是一種新的 Web 應(yīng)用架構(gòu)?;谶@種架構(gòu)開發(fā)的應(yīng)用中,服務(wù)器端會主動以異步的方式向客戶端程序推送數(shù)據(jù),而不需要客戶端顯式的發(fā)出請求。Comet 架構(gòu)非常適合事件驅(qū)動的 Web 應(yīng)用,以及對交互性和實時性要求很強的應(yīng)用,如股票交易行情分析、聊天室和 Web 版在線游戲等。本文在介紹 Comet 架構(gòu)的基礎(chǔ)上,詳細(xì)說明了如何利用 WebSphere Application Server Feature Pack for Web 2.0 和 Dojo 來開發(fā)基于 Comet 的應(yīng)用程序,并給出了兩個具體的實例。

Comet 及相關(guān)技術(shù)簡介

Comet 指的是一種 Web 應(yīng)用程序的架構(gòu)。在這種架構(gòu)中,客戶端程序(通常是瀏覽器)不需要顯式的向服務(wù)器端發(fā)出請求,服務(wù)器端會在其數(shù)據(jù)發(fā)生變化的時候主動的將數(shù)據(jù)異步的發(fā)送給客戶端,從而使得客戶端能夠及時的更新用戶界面以反映服務(wù)器端數(shù)據(jù)的變化。

developerWorks Ajax 資源中心

請訪問 Ajax 資源中心,這里幾乎囊括了關(guān)于 Ajax 編程模型的所有信息,包括各種文章、教程、論壇、博客、wikis、活動和新聞。

這種架構(gòu)既不同于傳統(tǒng)的 Web 應(yīng)用,也不同于新興的 Ajax 應(yīng)用。在傳統(tǒng)的 Web 應(yīng)用中,通常是客戶端主動的發(fā)出請求,服務(wù)器端生成整個 HTML 頁面交給客戶端去處理。在 Ajax 應(yīng)用中,同樣是客戶端主動的發(fā)出請求,只是服務(wù)器通常返回的是 XML 或是 JSON 格式的數(shù)據(jù),然后客戶端使用這些數(shù)據(jù)來對頁面進(jìn)行局部更新。Comet 架構(gòu)非常適合事件驅(qū)動的 Web 應(yīng)用和對交互性和實時性要求很強的應(yīng)用。這樣的應(yīng)用的例子包括股票交易行情分析、聊天室和 Web 版在線游戲等。

基于 Comet 架構(gòu)的 Web 應(yīng)用使用客戶端和服務(wù)器端之間的 HTTP 長連接來作為數(shù)據(jù)傳輸?shù)耐ǖ?。每?dāng)服務(wù)器端的數(shù)據(jù)因為外部的事件而發(fā)生改變時,服務(wù)器端就能夠及時把相關(guān)的數(shù)據(jù)推送給客戶端。通常來說,有兩種實現(xiàn)長連接的策略:

HTTP 流(HTTP Streaming)
這種情況下,客戶端打開一個單一的與服務(wù)器端的 HTTP 持久連接。服務(wù)器通過此連接把數(shù)據(jù)發(fā)送過來,客戶端增量的處理它們。
HTTP 長輪詢(HTTP Long Polling)
這種情況下,由客戶端向服務(wù)器端發(fā)出請求并打開一個連接。這個連接只有在收到服務(wù)器端的數(shù)據(jù)之后才會關(guān)閉。服務(wù)器端發(fā)送完數(shù)據(jù)之后,就立即關(guān)閉連接??蛻舳藙t馬上再打開一個新的連接,等待下一次的數(shù)據(jù)。

WebSphere Application Server Feature Pack for Web 2.0 簡介

WebSphere Application Server Feature Pack for Web 2.0 是 IBM 支持的解決方案,用于在 Websphere Application Server 上創(chuàng)建基于 Ajax 的應(yīng)用和 mashup。除了 Ajax 開發(fā)工具之外,該功能部件包還包含了對服務(wù)器端的增強功能,用來支持通用的 Web 2.0 應(yīng)用模式。該功能部件包提供了對開發(fā) Web 2.0 應(yīng)用的很多增強。主要有三個方面:Web 2.0 到 SOA 的連接性、Ajax 消息處理和 Ajax 開發(fā)工具箱。關(guān)于該功能部件包的具體內(nèi)容,請看 參考資源。該功能部件包有適用于 WebSphere Application Server 和 WebSphere Application Server Community Edition 的不同版本。

Dojox.cometd 簡介

Dojo 的創(chuàng)始人 Alex Russell 最開始提出“Comet”這個詞。Dojo 基金會提出了 Bayeux 協(xié)議用來標(biāo)準(zhǔn)化 Comet 應(yīng)用中客戶端和服務(wù)器端之間的通信。關(guān)于 Bayeux 協(xié)議的具體信息,請看 參考資源。Dojox.cometd 實現(xiàn)了 Bayeux 協(xié)議的客戶端部分,使用 HTTP 長輪詢來作為數(shù)據(jù)的傳輸通道。





回頁首


構(gòu)建開發(fā)環(huán)境

為了能夠開發(fā)使用 WebSphere Application Server Feature Pack for Web 2.0 的 Comet 應(yīng)用,需要下載 WebSphere Application Server Feature Pack for Web 2.0。WebSphere Application Server Feature Pack for Web 2.0 有適用于 WebSphere Application Server 和 WebSphere Application Server Community Edition 的不同版本,請注意下載正確的版本。本文中使用的是適用于 WebSphere Application Server Community Edition 的版本。適用于 WebSphere Application Server 上的版本的配置與 Community Edition 有所不同,您需要參考相應(yīng)的說明文檔。您可以在 參考資源 中找到相關(guān)的下載地址。

在下載并安裝好 WebSphere Application Server Community Edition 和相應(yīng)版本的 Feature Pack for Web 2.0 之后,就可以繼續(xù)下面的步驟了。為了能夠更加有效的開發(fā),我推薦使用 Eclipse 的 Web Tools Platform(WTP)來進(jìn)行開發(fā)。Eclipse WTP 集成了對各種應(yīng)用服務(wù)器的內(nèi)嵌支持,可以很容易的在 Eclipse 內(nèi)部啟動、停止和配置應(yīng)用服務(wù)器。Eclipse WTP 默認(rèn)沒有 WebSphere Application Server Community Edition 的支持,您需要通過 WTP 來手動安裝。您可以在 參考資源 中找到相關(guān)的下載地址。

您可以參考下面兩張截圖來為 WTP 安裝 WebSphere Application Server Community Edition 的支持。


圖 1. 在“New Server Runtime”選擇“Download additional server adapters”


圖 2. 在“Install New Server Adapter”中選擇“WASCE v2.0 Server Adapter”





回頁首


創(chuàng)建新的 Comet 項目

在為 Eclipse WTP 安裝完成對 WebSphere Application Server Community Edition 的支持之后,就可以開始創(chuàng)建 Comet 項目了。

創(chuàng)建 Comet 項目和一般的 Dynamic Web Project 是類似的。只是在選擇“Target Runtime”的時候要選擇“IBM WASCE v2.0”。如下圖所示:


圖 3. 創(chuàng)建新的 Comet 項目

接下來就按照向?qū)У哪J(rèn)選項就可以了。

為了啟用 WebSphere Application Server Community Edition 對 Comet 的支持,還需要做進(jìn)一步的配置。這些配置包括為 Tomcat 啟用 HTTP NIO 監(jiān)聽器,提供 JMS 消息服務(wù)等。關(guān)于這些配置的具體信息,可以在 Feature Pack for Web 2.0 中找到詳細(xì)的文檔。





回頁首


Comet 應(yīng)用基本架構(gòu)

使用 WebSphere Application Server Feature Pack for Web 2.0 和 Dojo 開發(fā)的 Comet 應(yīng)用由服務(wù)器端和客戶端兩部分組成。服務(wù)器端由 com.ibm.webmsg.servlet.BayeuxServlet 提供 HTTP 長連接支持,客戶端則由 dojox.cometd 包提供支持。兩者都實現(xiàn)了 Bayeux 協(xié)議。

服務(wù)器端

Comet 應(yīng)用的服務(wù)器端需要提供一個繼承自 com.ibm.webmsg.servlet.BayeuxServlet 的 Servlet 來提供與客戶端之間的持久 HTTP 連接。通常來說,這個 Servlet 的實現(xiàn)類似如下代碼所示:


清單 1. Comet 應(yīng)用服務(wù)器端代碼
                        public class BrownianMotionServlet extends BayeuxServlet {                        @Override                        public void registerURL() {                        getServletUtil().addClientManager("/brownianMotionServlet", clientManager);                        }                        @Override                        public void setProperties() {                        setCometTimeout(30000);                        setClientPollInterval(2);                        setRouterType(JMS);                        setClientsCanPublish(false);                        }                        }

首先,需要為該 Servlet 指定一個 URI 來傳送數(shù)據(jù),這是通過 registerURL 方法來實現(xiàn)的。接著可以在 setProperties 方法設(shè)置相關(guān)屬性:用 setCometTimeout 設(shè)置客戶端請求的超時時間;用 setClientPollInterval 設(shè)置客戶端請求之間的間隔時間;用 setRouterType 設(shè)置數(shù)據(jù)傳輸?shù)耐ǖ李愋?,目前有使用?nèi)存和 JMS 兩種可以選擇,分別用 setRouterType(SIMPLE)setRouterType(JMS) 來設(shè)置;用 setClientsCanPublish 設(shè)置客戶端是否可以發(fā)布數(shù)據(jù)。

當(dāng)服務(wù)端需要發(fā)布數(shù)據(jù)給客戶端的時候,可以通過 com.ibm.ws.webmsg.publisher.DataPublisherpublish 方法來發(fā)送針對特定主題的數(shù)據(jù)。

客戶端

客戶端為了能夠接收服務(wù)器端發(fā)布的數(shù)據(jù),首先要初始化到服務(wù)器端某個通道的連接,然后定義對于特定主題數(shù)據(jù)的處理方法。參看下面的代碼:


清單 2. Comet 應(yīng)用客戶端代碼
                        dojo.addOnLoad(function(){                        dojox.cometd.subscribe("/motion", window, "display");                        initControls();                        getTemperature();                        });

在上面的代碼中,dojox.cometd.init("brownianMotionServlet") 用來初始化到服務(wù)器端某個通道的連接。這里使用的 URI brownianMotionServlet 和之前在服務(wù)器端用 registerURL 方法聲明的 URI 是一樣的。dojox.cometd.subscribe 用來聲明對某個主題的數(shù)據(jù)執(zhí)行的處理。如上所示,每當(dāng)接收到名為“/motion”的主題的數(shù)據(jù)時,就調(diào)用 window 對象的 display 方法。接收到的數(shù)據(jù)會作為 display 方法的參數(shù)傳入。

在介紹完 Comet 應(yīng)用的基本架構(gòu)之后,接下來將通過兩個具體的例子來說明如何開發(fā) Comet 應(yīng)用。第一個例子是布朗運動的模擬。這個例子主要展示的是如何在服務(wù)器端將持續(xù)變化的數(shù)據(jù)以推送的方式發(fā)送給客戶端做處理。這個是典型的事件驅(qū)動的應(yīng)用。第二個例子是基于 Comet 的聊天室。這個例子主要展示的是如何利用 Comet 的客戶端發(fā)布數(shù)據(jù)的能力,把服務(wù)器作為數(shù)據(jù)傳輸?shù)目偩€。這個是典型的對交互性和實時性要求很強的應(yīng)用。





回頁首


布朗運動模擬

布朗運動指的是懸浮微粒不停地做無規(guī)則運動的現(xiàn)象。它是 1826 年由英國植物學(xué)家布朗用顯微鏡觀察懸浮在水中的花粉時發(fā)現(xiàn)的。不只是花粉和小炭粒,對于液體中各種不同的懸浮微粒,都可以觀察到布朗運動。布朗運動模擬在物理教學(xué)上有一定的意義,可以方便學(xué)生更直觀的看到微粒的運動情況。

下面的這個 Comet 應(yīng)用是在 Web 頁面上模擬布朗運動。布朗運動的模擬需要大量的數(shù)據(jù)計算,這樣的工作是交給服務(wù)器端來處理。服務(wù)器端根據(jù)一定的算法計算出每個微粒在不同時刻的位置,然后把相應(yīng)的數(shù)據(jù)推送給瀏覽器。瀏覽器負(fù)責(zé)根據(jù)這些數(shù)據(jù)生成相應(yīng)的用戶界面,方便用戶直觀的看到微粒的運動情況。

出于簡化問題的需要,該示例應(yīng)用中只是模擬少量的微粒,默認(rèn)只有 100 個微粒。它們的運動規(guī)律是每隔一段時間,其移動方向就會相對當(dāng)前方向發(fā)生一定的偏移。溫度越高,偏移的角度就越大。這是符合布朗運動的規(guī)律的。在瀏覽器端,是以紅色小方塊來表示微粒的當(dāng)前位置的。在瀏覽器端也提供用戶界面讓用戶設(shè)置模擬時的溫度,方便用戶看到溫度的改變對微粒運動的影響。

在該 Comet 應(yīng)用中,瀏覽器和服務(wù)器端既有數(shù)據(jù)流,又有控制流。數(shù)據(jù)流是通過 HTTP 長連接來傳輸數(shù)據(jù)的,而控制流是通過一般的 HTTP GET 和 POST 請求來實現(xiàn)的。數(shù)據(jù)流是用來傳輸布朗運動模擬中微粒的位置信息,而控制流用來獲取和設(shè)置模擬時的溫度。

數(shù)據(jù)流

首先介紹數(shù)據(jù)流。在應(yīng)用啟動之后,會啟動一個定時器(MotionTimer),該定時器定時的將模擬出來的微粒的位置數(shù)據(jù)以 JSON 格式發(fā)送到特定的主題上。這是通過 com.ibm.ws.webmsg.publisher.DataPublisherpublish 方法來實現(xiàn)的。


清單 3. 服務(wù)器端定時將微粒的位置信息以 JSON 格式推送給瀏覽器
                        public class AppInit extends javax.servlet.http.HttpServlet {                        private static final int SNAPSHOT_INTERVAL = 5000;                        private static final int PARTICLE_NUMBER = 100;                        public static final String TIMER_KEY = "PublishTimer";                        public static final String UPDATER_KEY = "MotionUpdater";                        public static final String MOTION_TOPIC = "/motion";                        private static final Logger logger = Logger.getLogger(AppInit.class.getName());                        @Override                        public void init() throws ServletException {                        super.init();                        MotionSnapshot snapshot = new MotionSnapshot();                        snapshot.setParticles(ParticleGenerator.generate(PARTICLE_NUMBER));                        MotionUpdater updater = new MotionUpdater();                        getServletContext().setAttribute(UPDATER_KEY, updater);                        try {                        DataPublisher publisher = new DataPublisher();                        Timer timer = new Timer();                        //創(chuàng)建定時器                        MotionTimer mt = new MotionTimer(snapshot, updater, publisher);                        timer.scheduleAtFixedRate(mt, 1000, SNAPSHOT_INTERVAL);                        getServletContext().setAttribute(TIMER_KEY, timer);                        logger.info("Brownian motion simulation started successfully.");                        } catch (Exception e) {                        logger.log(Level.WARNING, e.getMessage(), e);                        }                        }                        private class MotionTimer extends TimerTask {                        private MotionSnapshot snapshot;                        private MotionUpdater updater;                        private DataPublisher publisher;                        public MotionTimer(MotionSnapshot snapshot, MotionUpdater updater,                        DataPublisher publisher) {                        this.snapshot = snapshot;                        this.updater = updater;                        this.publisher = publisher;                        }                        @Override                        public void run() {                        updater.update(snapshot);                        List<PositionPair> pairs = snapshot.getSnapshot();                        StringBuilder builder = new StringBuilder();                        builder.append("[");                        for (PositionPair pair : pairs) {                        builder.append("{\"x\":");                        builder.append(pair.getPosX());                        builder.append(",\"y\":");                        builder.append(pair.getPosY());                        builder.append("},");                        }                        builder.deleteCharAt(builder.length() - 1);                        builder.append("]");                        try {                        //發(fā)送數(shù)據(jù)                        publisher.publish(MOTION_TOPIC, builder.toString());                        } catch (JMSException e) {                        logger.log(Level.WARNING, e.getMessage(), e);                        }                        }                        }                        }                        

瀏覽器端只需要在同樣的主題上注冊處理相應(yīng)的方法就可以對服務(wù)器端發(fā)布的數(shù)據(jù)進(jìn)行處理。這是通過 dojox.cometd.subscribe 方法來實現(xiàn)的。


清單 4. 瀏覽器端處理微粒位置信息
                        dojo.require("dojox.cometd");                        dojo.addOnLoad(function(){                        dojox.cometd.init("brownianMotionServlet")                        dojox.cometd.subscribe("/motion", window, "display");                        initControls();                        getTemperature();                        });                        function display(msg){                        dojo.byId("motionArea").innerHTML = "";                        dojo.forEach(msg.data || [], function(particle) {                        var div = dojo.doc.createElement("div");                        dojo.addClass(div, "particle");                        dojo._setBox(div, particle.x, particle.y);                        dojo.byId("motionArea").appendChild(div);                        });                        }                        

從上面可以看到,瀏覽器端根據(jù)服務(wù)器端發(fā)布的微粒的位置信息,以一個 HTML DIV 元素表示一個微粒,并放置在適當(dāng)?shù)奈恢谩?/p>

控制流

對于控制流的處理相對簡單。處理控制邏輯的是一個普通的 Servlet,在其 doGetdoPost 方法中實現(xiàn)獲取和設(shè)置溫度的邏輯。


清單 5. 服務(wù)器端處理控制邏輯的代碼
                        public class MotionControlServlet extends HttpServlet implements Servlet {                        private static final int MAX_TEMPERATURE = 200;                        private static final Logger logger = Logger                        .getLogger(MotionControlServlet.class.getName());                        @Override                        protected void doGet(HttpServletRequest req, HttpServletResponse resp)                        throws ServletException, IOException {                        resp.setContentType("text/plain");                        String operation = req.getParameter("operation");                        if (operation == null) {                        logger.warning("Client has sent empty operation!");                        resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);                        resp.getOutputStream().print("Please specify the operation!");                        return;                        }                        if (operation.equalsIgnoreCase("getTemperature")) {                        MotionUpdater updater = (MotionUpdater) getServletConfig()                        .getServletContext().getAttribute(AppInit.UPDATER_KEY);                        if (updater != null) {                        int temperature = updater.getTemperature();                        resp.setStatus(HttpServletResponse.SC_OK);                        resp.getOutputStream().print(temperature);                        }                        else {                        resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);                        resp.getOutputStream()                        .print("Can not get the temperature, please try again later!");                        }                        } else {                        resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);                        resp.getOutputStream().print("Unknown operation type!");                        }                        }                        @Override                        protected void doPost(HttpServletRequest req, HttpServletResponse resp)                        throws ServletException, IOException {                        resp.setContentType("text/plain");                        String operation = req.getParameter("operation");                        if (operation == null) {                        logger.warning("Client has sent empty operation!");                        resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);                        resp.getOutputStream().print("Please specify the operation!");                        return;                        }                        if (operation.equalsIgnoreCase("changeTemperature")) {                        String tempStr = req.getParameter("temperature");                        if (tempStr == null || tempStr.trim().equals("")) {                        logger.warning("Client has sent empty value of temperature!");                        resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);                        resp.getOutputStream().print("Please specify the temperature!");                        return;                        }                        int temperature = 0;                        try {                        temperature = Math.min(Integer.parseInt(tempStr),                        MAX_TEMPERATURE);                        } catch (NumberFormatException nfe) {                        logger.log(Level.WARNING,                        "Client has sent invalid value of temperature!", nfe);                        resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);                        resp.getOutputStream()                        .print("The value of temperature must be a number!");                        return;                        }                        resp.setStatus(HttpServletResponse.SC_OK);                        MotionUpdater updater = (MotionUpdater) getServletConfig()                        .getServletContext().getAttribute(AppInit.UPDATER_KEY);                        if (updater != null) {                        updater.setTemperature(temperature);                        resp.getOutputStream().print(temperature);                        logger.info("Temperature has been changed to " + temperature);                        }                        } else {                        resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);                        resp.getOutputStream().print("Unknown operation type!");                        }                        }                        }                        

在瀏覽器端,使用 Dojo 的 xhrGetxhrPost 來與服務(wù)器端交互。


清單 6. 瀏覽器端處理控制邏輯的代碼
                        //獲取模擬時的溫度                        function getTemperature() {                        var messageBox = dojo.byId("messageBox");                        messageBox.innerHTML = "";                        dojo.xhrGet({                        url : "/BrownianMotion/control?operation=getTemperature",                        handleAs : "text",                        load : function(response) {                        var temperature = dojo.byId("temperature");                        temperature.innerHTML = response;                        },                        error : function(response, ioArgs) {                        messageBox.innerHTML = ioArgs.xhr.responseText;                        }                        });                        }                        //更新模擬時的溫度                        function updateTemperature() {                        var messageBox = dojo.byId("messageBox");                        messageBox.innerHTML = "";                        var tempInput = dojo.byId("temperatureInput");                        var value = dojo.trim(tempInput.value);                        if (value.length > 0) {                        dojo.xhrPost({                        url : "/BrownianMotion/control",                        handleAs : "text",                        content : {                        "operation" : "changeTemperature",                        "temperature" : value                        },                        load : function(response) {                        var temperature = dojo.byId("temperature");                        temperature.innerHTML = response;                        },                        error : function(response) {                        messageBox.innerHTML = ioArgs.xhr.responseText;                        }                        });                        }                        }                        

該 Comet 應(yīng)用實際運行的截圖如下:


圖 4. 布朗運動模擬的 Comet 應(yīng)用截圖





回頁首


基于 Comet 的聊天室

前面提到過,Comet 架構(gòu)比較適合交互性和實時性要求比較高的應(yīng)用,聊天室就是其中的一種。在聊天室中,用戶總是希望自己的發(fā)送的消息能更快的讓其他用戶看到,同時能夠更快的看到其他用戶的消息。

在聊天室這個應(yīng)用中,主要使用客戶端發(fā)送數(shù)據(jù),服務(wù)器端只是負(fù)責(zé)中轉(zhuǎn)數(shù)據(jù)。需要在服務(wù)器端的 Servlet 設(shè)置 setClientsCanPublish(true)。在聊天室中同時有多個用戶,當(dāng)其中一個用戶輸入了消息之后,服務(wù)器會把這些消息廣播給在聊天室的其他用戶。


清單 7. 聊天室服務(wù)器端代碼
                        public class MeetingRoomServlet extends BayeuxServlet {                        @Override                        public void registerURL() {                        getServletUtil().addClientManager("/meetingRoomServlet", clientManager);                        }                        @Override                        public void setProperties() {                        setCometTimeout(30000);                        setClientPollInterval(5);                        setRouterType(SIMPLE);                        setClientsCanPublish(true);                        }                        }                        


清單 8. 聊天室客戶端主要的 JavaScript
                        var MeetingRoom = (function() {                        var nickName = "匿名用戶";                        var chatArea;                        var topic = "/chat";                        return {                        //顯示消息                        displayMessage : function(msgObject) {                        var date = new Date();                        try {                        date.setTime(msgObject["dateTime"]);                        }                        catch (error) {                        }                        var msg = ["<b>",                        decodeURIComponent(msgObject["sender"]) || "匿名用戶",                        "</b> 說:",                        decodeURIComponent(msgObject["message"]),                        "  (", date.toLocaleString(), ")"].join("");                        var div = dojo.doc.createElement("div");                        div.innerHTML = msg;                        chatArea.appendChild(div);                        },                        //發(fā)送消息                        sendMessage : function(message) {                        message = dojo.trim(message);                        if (message.length > 0) {                        dojox.cometd.publish(topic,                        {"sender" : encodeURIComponent(nickName),                        "message": encodeURIComponent(message),                        "dateTime" : new Date().getTime()});                        }                        },                        //修改昵稱                        changeNickName : function(newNickName) {                        nickName = newNickName;                        },                        init : function() {                        chatArea = dojo.byId("chatArea");                        }                        }                        })();                        

該聊天室實際運行起來的截圖如下,我使用了幾個不同的瀏覽器,并用了不同的用戶來模擬多用戶的效果。


圖 5. 聊天室應(yīng)用截圖





回頁首


總結(jié)

本文從兩個實例出發(fā),具體地介紹了如何使用 WebSphere Application Server Feature Pack for Web 2.0 和 Dojo 開發(fā)基于 Comet 架構(gòu)的應(yīng)用程序。可以看到,Comet 架構(gòu)在很多的應(yīng)用場景下都是很適合的。WebSphere Application Server Feature Pack for Web 2.0 和 Dojo 為開發(fā)這樣的應(yīng)用提供了良好的支持,可以作為很好的出發(fā)點。





回頁首


聲明

本文章僅代表作者本人觀點,與 IBM 公司無關(guān)。






回頁首


下載

描述 名字 大小 下載方法
布朗運動模擬 Comet 應(yīng)用源代碼 BrownianMotion.zip 9KB HTTP
聊天室 Comet 應(yīng)用源代碼 ChatRoom.zip 4KB HTTP
關(guān)于下載方法的信息


參考資料

學(xué)習(xí)

獲得產(chǎn)品和技術(shù)





關(guān)于作者

 

成富任職于 IBM 中國軟件開發(fā)中心,目前在 CETI Web 2.0 小組從事開發(fā)工作。他畢業(yè)于北京大學(xué)信息科學(xué)技術(shù)學(xué)院,獲得計算機軟件與理論專業(yè)碩士學(xué)位。

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
為 WebSphere Application Server Community Edit...
Comet簡介
JavaEE中Web服務(wù)器、Web容器、Application服務(wù)器區(qū)別及聯(lián)系
Apache與Tomcat的區(qū)別 ,幾種長見得web/應(yīng)用服務(wù)器 - limingbupt...
WebSphere性能優(yōu)化:你需要多大的池? - WebSphere 開發(fā)與應(yīng)用社區(qū) :W...
常用的java應(yīng)用服務(wù)器
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服