標籤:
項目的原因需要實現基於Web版的網上報價查詢系統。使用者需求很簡單就是客戶通過登入網站後,可以對產品提交買賣價格,系統有個集中展示螢幕來展示10檔最優買入和賣出價格。對於上述功能的實現無外乎有兩種實現方式:
推送(Push)技術:
一種建立在伺服器上的機制,由伺服器主動將資訊發往用戶端的技術。Push技術的優勢在於資訊主動性和及時性。
拉(Pull)技術:
客戶機主動請求資訊,採用用戶端定時重新整理頁面,可使用Ajax技術實現,每隔N秒自動Reload一次,如果在此期間Server端資料發生變化,用戶端可以擷取新的內容。
根據我們的需求,採用推送技術來實現上述功能是個比較好的選擇。經過技術選型,最終選擇使用Pushlet架構。Pushlet採用觀察者模式,客訂閱伺服器感興趣的事件,伺服器端為每個用戶端分配一個Session ID為標記,事件來源會把新產生俄事件以多播的方式發送到訂閱者的事件隊列裡。具體原理這裡不作過多介紹,本文主要介紹一下使用Pushlet實現的一個計算報價平均值的Demo。
建立一個QuoteServlet.類,一個Servlet用於實現從用戶端提交使用者的報價,並觸發伺服器端發送價格變動事件。
package com;import java.io.IOException;import java.io.PrintWriter;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;/* * Servlet方法實現資料的提交 */public class QuoteServlet extends HttpServlet{private static final long serialVersionUID = 2386052823761867369L;public static Double ttPrice = 0.00;public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{// 調用 HttpServlet 內建的日誌函數輸出資訊到控制台this.log("執行 doGet 方法... ");// 處理 doPostthis.execute(request, response);//調用pushlet更新對方的資料String valueString = Double.toString(ttPrice);QuotePushlet.sendByMulticast(valueString);}/** * 以 POST 方式訪問頁面時執行該函數。 */ public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {this.log("執行 doPost 方法... ");// 處理 doPostthis.execute(request, response);//調用pushlet更新對方的資料String valueString = Double.toString(ttPrice);//定向廣播//QuotePushlet.sendByMulticast(valueString);//定向發送QuotePushlet.sendByUnicast(valueString);//QuotePushlet.sendByBroadcast(valueString);}private void execute(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException{String priceString = getReqStr(request.getParameter("qprice"),true);Double priceDb = 0.0;if (priceString != null && priceString != ""){priceDb = Double.valueOf(priceString);} if (ttPrice != 0.00){ttPrice = ttPrice + priceDb;ttPrice = ttPrice/2;}else{ttPrice = priceDb;}} private String getReqStr(Object s,boolean isGetMethod){ if(s==null) return ""; if(!isGetMethod) return ((String)s).toString(); try{ return new String(((String)s).toString().getBytes("ISO8859_1"), "GBK"); }catch(Exception e){ return ""; } }}
建立QuotePushlet類,用於實現事件廣播。我這邊分別使用了Pushlet的unicast,multicast,broadcast來發送廣播事件。其中unicast是定向發,multicast,broadcast都是全域廣播。
package com;import java.util.HashMap;import java.util.Map;import nl.justobjects.pushlet.core.Dispatcher;import nl.justobjects.pushlet.core.Event;import nl.justobjects.pushlet.core.Session;import nl.justobjects.pushlet.core.SessionManager;/* * 使用push的broadcast,multicast,unicast方法 * * 實現資料的展示 */public class QuotePushlet {public static void sendByMulticast(String value){Map<String, String> map = new HashMap<String, String>();map.put("avgPrice", value);Event event = null;event = Event.createDataEvent("/quote/newPrice", map);//群發廣播Dispatcher.getInstance().multicast(event);}public static void sendByUnicast(String value){Map<String, String> map = new HashMap<String, String>();map.put("avgPrice", value);Event event = null;event = Event.createDataEvent("/quote/newPrice", map);Session[] sessions = SessionManager.getInstance().getSessions();for ( Session session : sessions ) {//定向發送Dispatcher.getInstance().unicast(event, session.getId());}}public static void sendByBroadcast(String value){Map<String, String> map = new HashMap<String, String>();map.put("avgPrice", value);Event event = null;event = Event.createDataEvent("/quote/newPrice", map);Dispatcher.getInstance().broadcast(event);}}使用pushlet需要在Web.xml裡進行配置。
<?xml version="1.0" encoding="UTF-8"?><web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"><!-- Define the pushlet servlet --><servlet><servlet-name>pushlet</servlet-name><servlet-class>nl.justobjects.pushlet.servlet.Pushlet</servlet-class><load-on-startup>3</load-on-startup></servlet><!-- Define the Servlet Mappings. --><!-- The pushlet --><servlet-mapping><servlet-name>pushlet</servlet-name><url-pattern>/pushlet.srv</url-pattern></servlet-mapping><servlet><servlet-name>quoteServlet</servlet-name><servlet-class>com.QuoteServlet</servlet-class></servlet><servlet-mapping><servlet-name>quoteServlet</servlet-name><url-pattern>/quoteServlet</url-pattern></servlet-mapping></web-app>
另外還需要pushlet.properties和sources.properties,這裡不表啦。
報價的JSP頁面代碼如下:
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><title>quote</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta http-equiv="Pragma" content="no-cache"> <script type="text/javascript" src="ajax-pushlet-client.js"></script> <link rel="stylesheet" type="text/css" href="./script/easyui/jquery-easyui-1.3.5/easyui.css" ><link rel="stylesheet" type="text/css" href="./script/easyui/jquery-easyui-1.3.5/icon.css" ><script type="text/javascript" src="./script/easyui/jquery.min.js"></script><script type="text/javascript" src="./script/easyui/jquery.easyui.min.js"></script> <style type="text/css" ID="PageStyle"> body, td{ background: #ffffff; color: #000000; font-size: 14px; font-family : verdana, sans-serif;} body { margin-left: 8px; margin-right: 0px;} .head { color: #111111;}</style><script type="text/javascript"> function QuotationPost(){ $.ajax({ type: "post", url: "quoteServlet", dataType: "text", data:{qprice:$("#formqprice").val()}, success: function (data) { }, error: function (XMLHttpRequest, textStatus, errorThrown) { alert(errorThrown); } });}</script></head><body><div><span>當前債券的平均價格是</span> <span id="qprice"></span> <br></div><div> <span>我要報價:</span> <div style="font-size: 20px;" > <form id="QuotationForm" method="post" > <table> <tr> <td colspan="3" > 報價: <input name="qprice" id="formqprice" type="text" style="width:100px" /> </td> </tr> <tr> <td colspan="2" > <input type="button" value="提交報價" onclick="QuotationPost();" /> </td> </tr></table> </form> </div></div></body></html>
價格展示的前台頁面如下:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><meta http-equiv="Pragma" content="no-cache" /><script type="text/javascript" src="ajax-pushlet-client.js"></script><script type="text/javascript">PL._init(); PL.joinListen('/cuige/he');function onData(event) { //alert(event.get("mmdata")); // 離開// PL.leave();var kbDom = document.getElementById('kb');var kb = event.get("mess");//alert(event.get("mmdata"));kbDom.innerHTML = kb;}</script></head><body>當前債券平均價格:<span id="kb">...</span>元</body></html>
基於Pushlet實現的Web版報價系統