附件里Pushlet和Dwr3.0的简单服务器推技术。
DWR-Source.rar为DWR的学习资料。
下面简单介绍一下dwr3.0 RC2版本的反推技术代码。
首先下载dwr官方包,笔者这里下载的是dwr3.0 RC2开发包。
把dwr.jar和engine.js等相关文件放入web工程里。
首先在web.xml文件的同级目录建立dwr.xml文件,其内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 3.0//EN" "http://getahead.org/dwr/dwr30.dtd">
<dwr>
<allow>
<!-- stockpusher -->
<create creator="new" scope="application" javascript="StocksPusher">
<param name="class" value="com.shihuan.dragonkeeper.server.reverseajax.stockspusher.StocksPusher"/>
</create>
</allow>
</dwr>
在web.xml文件中要加入如下代码:
<listener>
<listener-class>org.directwebremoting.servlet.DwrListener</listener-class>
</listener>
<servlet>
<servlet-name>dwr-invoker</servlet-name>
<servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>accessLogLevel</param-name>
<param-value>runtimeexception</param-value>
</init-param>
<init-param>
<param-name>activeReverseAjaxEnabled</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>initApplicationScopeCreatorsAtStartup</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>jsonRpcEnabled</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>jsonpEnabled</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>preferDataUrlSchema</param-name>
<param-value>false</param-value>
</init-param>
//下面这句要看你的web工程中是否有优先于dwr启动的文件
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dwr-invoker</servlet-name>
//下面的resources目录的意思是笔者dwr的引擎文件是放在WebRoot/resources/dwr目录下面的(engine.js)
<url-pattern>/resources/dwr/*</url-pattern>
</servlet-mapping>
StocksPusher.java代码如下:
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.dbutils.DbUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.directwebremoting.Browser;
import org.directwebremoting.ScriptSessions;
import org.directwebremoting.impl.DaemonThreadFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.fastjson.JSON;
import com.shihuan.dragonkeeper.common.dto.DataSourceInfo;
import com.shihuan.dragonkeeper.common.utils.DataSourceMapUtil;
import com.shihuan.dragonkeeper.common.utils.PropertiesUtil;
import com.shihuan.dragonkeeper.global.ConfigFile;
import com.shihuan.dragonkeeper.server.bean.StocksBean;
public class StocksPusher implements Runnable {
protected static Logger logger = LoggerFactory.getLogger(StocksPusher.class);
private static String jdbc_CONFIG = ConfigFile.JDBC_CONFIG + ConfigFile.SUFFIX_NAME;
private static boolean closeMarket = false;
public StocksPusher() {
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1, new DaemonThreadFactory());
executor.scheduleAtFixedRate(this, 1L, 50L, TimeUnit.MILLISECONDS);
}
@Override
public void run() {
if (!closeMarket) {
StocksBean stock = StockPriceTracer.getNextStockInfo(); //获取后台数据
// setMessageToPage(stock.getStock(), stock.getValue()); //非JSON版本
insertDbData(stock);
setJsonMessageToPage(JSON.toJSON(stock));
}
}
public void setJsonMessageToPage(final Object json){
Browser.withAllSessions(new Runnable() {
public void run() {
ScriptSessions.addFunctionCall("showJsonMessage", json);
}
});
}
public void setMessageToPage(final String key, final String message){
Browser.withAllSessions(new Runnable() {
public void run() {
ScriptSessions.addFunctionCall("showMessage", key, message);
}
});
}
public void insertDbData(final StocksBean data){
Thread t = new Thread(new Runnable() {
@Override
public void run() {
String sql = "insert into stocks(stock,value) values (?,?)";
QueryRunner queryRunner = new QueryRunner(true);
Connection conn = null;
DataSourceInfo dsObj = new DataSourceInfo();
try {
dsObj.setDriverClass(PropertiesUtil.getPropertiesValue(jdbc_CONFIG, "mysql.driverclass"));
dsObj.setJdbcUrl(PropertiesUtil.getPropertiesValue(jdbc_CONFIG, "mysql.jdbcurl"));
dsObj.setUser(PropertiesUtil.getPropertiesValue(jdbc_CONFIG, "mysql.user"));
dsObj.setPassword(PropertiesUtil.getPropertiesValue(jdbc_CONFIG, "mysql.password"));
conn = DataSourceMapUtil.getConnection(dsObj);
queryRunner.update(conn, sql, data.getStock(), data.getValue());
DbUtils.commitAndCloseQuietly(conn);
} catch (ConfigurationException e) {
DbUtils.rollbackAndCloseQuietly(conn);
logger.error(e.getMessage(), e);
e.printStackTrace();
} catch (SQLException e) {
DbUtils.rollbackAndCloseQuietly(conn);
logger.error(e.getMessage(), e);
e.printStackTrace();
} catch (IOException e) {
DbUtils.rollbackAndCloseQuietly(conn);
logger.error(e.getMessage(), e);
e.printStackTrace();
} finally {
try {
if (conn != null && !conn.isClosed()) {
conn.close();
}
} catch (SQLException e) {
logger.error(e.getMessage(), e);
e.printStackTrace();
}
}
}
});
t.start();
}
public void beginShow() {
closeMarket = false;
}
public void closeShow() {
closeMarket = true;
}
}
StockPriceTracer.java代码如下:
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Stack;
import com.shihuan.dragonkeeper.server.bean.StocksBean;
public class StockPriceTracer {
private static StockPriceTracer tracer = null;
private List<StocksBean> stocks = new ArrayList<StocksBean>();
private Stack<StocksBean> cycleStack = new Stack<StocksBean>();
private StockPriceTracer() {
stocks.add(new StocksBean("zsy", "36.55"));
stocks.add(new StocksBean("dlsd", "91.01"));
stocks.add(new StocksBean("zsh", "22.59"));
stocks.add(new StocksBean("lggf", "5.07"));
stocks.add(new StocksBean("hedq", "71.77"));
stocks.add(new StocksBean("jdsn", "31.61"));
stocks.add(new StocksBean("yyrj", "51.29"));
stocks.add(new StocksBean("zsyh", "52.70"));
stocks.add(new StocksBean("zgtj", "16.96"));
stocks.add(new StocksBean("sfz", "54.34"));
stocks.add(new StocksBean("jsrj", "178.48"));
stocks.add(new StocksBean("zyd", "134.48"));
stocks.add(new StocksBean("jzg", "76.32"));
stocks.add(new StocksBean("zgpa", "80.63"));
stocks.add(new StocksBean("gsyh", "18.79"));
stocks.add(new StocksBean("aggf", "20.19"));
stocks.add(new StocksBean("zght", "11.13"));
}
public static StocksBean getNextStockInfo() {
if (null == tracer) {
tracer = new StockPriceTracer();
}
if (tracer.cycleStack.empty()) {
tracer.cycleStack.addAll(tracer.stocks);
}
StocksBean tmp = tracer.cycleStack.pop();
tmp.setValue(tracer.getRandomPrice(tmp.getValue()));
return tmp;
}
private String getRandomPrice(String current) {
float fcurrent = 0.0F;
try {
fcurrent = Float.parseFloat(current);
} catch (NumberFormatException e) {
fcurrent = 0.01F;
}
Random rdm = new Random();
float tmp = fcurrent + rdm.nextFloat();
return String.valueOf(tmp);
}
}
StocksPusher.jsp代码如下:
<%@ page contentType="text/html;charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%@ page isELIgnored="false" %>
<fmt:requestEncoding value="UTF-8"/>
<c:set var="ctx" value="${pageContext.request.contextPath}"/>
<c:set var="requestURI" value="${pageContext.request.servletPath}"/>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>My Dwr Reverse Ajax Test For StocksInfo</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" type="text/css" href="${ctx}/resources/dwr/css/generic.css" />
<script type='text/javascript' src='${ctx}/resources/dwr/engine.js'></script>
<script type='text/javascript' src='${ctx}/resources/dwr/util.js'></script>
<script type='text/javascript' src='${ctx}/resources/dwr/interface/StocksPusher.js'></script>
<script type="text/javascript" src="${ctx}/resources/appbusiness/stockspusher/StocksPusher.js"></script>
</head>
<body>
<h3>使用DWR Reverse Ajax进行股票报盘</h3>
<p>下面显示的股票信息是可以动态变化的</p>
<input type="button" value="开市..." onclick="beginShow();" />
=========================
<input type="button" value="闭市..." onclick="endShow();" />
<hr />
<table style="width:500px;" border="0" cellpadding="0">
<tr>
<td class="headName">
<b>Stock Name</b>
</td>
<td class="headValue" >
<b>Stock Value</b>
</td>
</tr>
<tr><td>中移动</td><td><div id="zyd">wait...</div></td></tr>
<tr><td>中石化</td><td><div id="zsh">wait...</div></td></tr>
<tr><td>中石油</td><td><div id="zsy">wait...</div></td></tr>
<tr><td>海尔电器</td><td><div id="hedq">wait...</div></td></tr>
<tr><td>冀东水泥</td><td><div id="jdsn">wait...</div></td></tr>
<tr><td>用友软件</td><td><div id="yyrj">wait...</div></td></tr>
<tr><td>柳钢股份</td><td><div id="lggf">wait...</div></td></tr>
<tr><td>招商银行</td><td><div id="zsyh">wait...</div></td></tr>
<tr><td>中国铁建</td><td><div id="zgtj">wait...</div></td></tr>
<tr><td>深发展</td><td><div id="sfz">wait...</div></td></tr>
<tr><td>金山软件</td><td><div id="jsrj">wait...</div></td></tr>
<tr><td>大连实德</td><td><div id="dlsd">wait...</div></td></tr>
<tr><td>九寨沟</td><td><div id="jzg">wait...</div></td></tr>
<tr><td>中国平安</td><td><div id="zgpa">wait...</div></td></tr>
<tr><td>工商银行</td><td><div id="gsyh">wait...</div></td></tr>
<tr><td>鞍钢股份</td><td><div id="aggf">wait...</div></td></tr>
<tr><td>中国航天</td><td><div id="zght">wait...</div></td></tr>
</table>
<br />
</body>
</html>
StocksPusher.js代码如下:
window.onload = function() {
dwr.engine.setActiveReverseAjax(true);
};
function beginShow() {
StocksPusher.beginShow();
}
function endShow() {
StocksPusher.closeShow();
}
//JSON版本
function showJsonMessage(json){
if(json['stock'] != undefined || json['value'] != undefined){
document.getElementById(json['stock']).innerHTML = json['value'];
}
}
//非JSON版本
function showMessage(key, value){
document.getElementById(key).innerHTML = value;
}