需求:提醒用户30分钟内即将到期的预约
分析:如果是单纯采用很短时间间隔的轮询来判断并获取30分钟内的有效数据会发出很多不必要的请求,或者不准确的请求。也比较消耗资源。
如果单纯采用服务器推送技术,只能保证在发生推送的时候,能够获取到正确的数据,在不推送(同时增加数条几小时后的数据,则这几小时后的数据,在没有推送的情况下是无法获取的)或者推送前(如用户刚刚登陆时)是获取不到的。
解决方案: 1、用户登陆后进入页面即获取数据,并取得下一次要发送请求获取数据的时间(即数据队列中第一条30分钟以外的数据)。这样的话就避免了不间断的轮询。
2、在没有任何用户新增预约数据时,上面的方法已经可以满足需求了。但是如果有用户新增了数据,这个时候,第1步中获取的下一次发送请求的时间就有可能因为新插入的数据而不准确,所以在可以新增数据的入口,都采用服务器推送(精确推送到指定用户指定页面)让相关用户的页面自动触发第1步。
第1步代码:
1.1 HTML页面
var timeoutFun = null; function getNextTimeForRequestReserve { $.ajax({ url : url, data : data, type : "POST", success : function (data) { var nextTimeForRequestReserve = data.nextTimeForRequestReserve; if(nextTimeForRequestReserve && nextTimeForRequestReserve != "null") { if(timeoutFun) { clearTimeout(timeoutFun); } timeoutFun = setTimeout(function (){getNextTimeForRequestReserve()}, nextTimeForRequestReserve); } } }); }
1.2 Action
nextTimeForRequestReserve = this.reserveBiz.getTimeForNextRequest(queryObj);
1.3 Biz
public Long getTimeForNextRequest(QueryObj queryObj) { Long reuslt = null; String timeRange = queryObj.getQueryValue("timerange"); String nowTime = queryObj.getQueryValue("date"); Reserve reserve = this.reserveDao.getReserveForCalculateNextReqTime(queryObj); if(reserve != null) { reuslt = reserve.getRecallDateStart().getTime() - Long.parseLong(nowTime) - 1000L * 60L * Long.parseLong(timeRange); } return reuslt; }
1.4 Dao
public Reserve getReserveForCalculateNextReqTime(QueryObj queryObj) { //timerange==>30 minutes String timeRange = queryObj.getQueryValue("timerange"); String userId = queryObj.getQueryValue("creater"); final String sql = "select {trra.*} from " + "(select * from reserve_record trr " + "where trr.creater = ‘" + userId + "‘ and (recall_result = 0 or recall_result is null) and trunc(trr.recall_date_start, ‘MI‘) > " + "trunc(sysdate + interval ‘" + timeRange + "‘ MINUTE, ‘MI‘) order by trr.recall_date_start) trra" + " where rownum = 1 "; Reserve result = getHibernateTemplate().execute(new HibernateCallback<Reserve>(){ @SuppressWarnings("unchecked") public Reserve doInHibernate(Session session) throws HibernateException, SQLException { SQLQuery sqlQuery = session.createSQLQuery(sql); sqlQuery.addEntity("trra", Reserve.class); List<Reserve> resultList = sqlQuery.list(); if(CollectionUtils.isNotEmpty(resultList)) { return resultList.get(0); } return null; } }); return result; }
第2步代码:
web.xml中
<servlet> <servlet-name>dwr-invoker</servlet-name> <servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class> <init-param> <param-name>activeReverseAjaxEnabled</param-name> <param-value>true</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>dwr-invoker</servlet-name> <url-pattern>/dwr/*</url-pattern> </servlet-mapping>
类路径下dwr.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN" "http://getahead.org/dwr/dwr20.dtd"> <dwr> <allow> <create creator="new" javascript="SendMessage" scope="application"> <param name="class" value="com.module.call.action.SendMessage"/> </create> </allow> </dwr>
public class SendMessage { public void send(String userTag) { ScriptBuffer scriptBuffer = new ScriptBuffer(); scriptBuffer.appendScript("showReserveMessage()"); WebContext webContext = WebContextFactory.get(); String page = "/frontPageManage/showFrontPage.action"; Collection<ScriptSession> scSession = webContext.getScriptSessionsByPage(page); for(ScriptSession s : scSession) { if(userTag.equals(s.getAttribute("userTag"))) { s.addScript(scriptBuffer); } } } public void setUserTag(String userTag) { ScriptSession scriptSession = WebContextFactory.get().getScriptSession(); scriptSession.setAttribute("userTag", userTag); } }
需要实现功能的页面
<script type=‘text/javascript‘ src=‘../dwr/engine.js‘> </script> <script type="text/javascript" src="../dwr/interface/SendMessage.js"> </script>
页面加载完成需要执行
dwr.engine.setActiveReverseAjax(true); SendMessage.setUserTag(currentUser);
Dwr调用的方法
function showReserveMessage() { getNextTimeForRequestReserve(); }
时间: 2024-10-18 10:29:01