dwr 推送实现
我們項目用的是spring + dwr ,基本配置這里不多說了
dwr推送方式有三種,這三種方式,都可以在dwr的配置文件中進行相關(guān)的配置,若不進行配置,則默認是下面的第一種piggyback。
? 1、piggyback方式
?????????? 這是默認的方式。
?????????? 如果后臺有什么內(nèi)容需要推送到前臺,是要等到那個頁面進行下一次ajax請求的時候,將需要推送的內(nèi)容附加在該次請求之后,傳回到頁面。
?????????? 只有等到下次請求頁面主動發(fā)起了,中間的變化內(nèi)容才傳遞回頁面。
?
????? 2、comet方式
?????????? 當服務端建立和瀏覽器的連接,將頁面內(nèi)容發(fā)送到瀏覽器之后,對應的連接并不關(guān)閉,只是暫時掛起。如果后面有什么新的內(nèi)容需要推送到客戶端的時候直接通過前面掛起的連接再次傳送數(shù)據(jù)。
?????????? 服務器所能提供的連接數(shù)目是一定的,在大量的掛起的連接沒有關(guān)閉的情況下,可能造成新的連接請求不能接入,從而影響到服務質(zhì)量。
?
????? 3、polling方式
?????????? 由瀏覽器定時向服務端發(fā)送ajax請求,詢問后臺是否有什么內(nèi)容需要推送,有的話就會由服務端返回推送內(nèi)容。這種方式和我們直接在頁面通過定時器發(fā)送 ajax請求,然后 查詢后臺是否有變化內(nèi)容的實現(xiàn)是類似的。只不過用了dwr之后這部分工作由框架幫我們完成了。
三種方式配置方式如下,在web.xml中加入
<servlet><servlet-name>dwr-invoker</servlet-name><servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class><init-param><param-name>debug</param-name><param-value>true</param-value></init-param><!-- DWR默認采用piggyback方式 --><!-- 使用polling和comet的方式 --><init-param><param-name>pollAndCometEnabled</param-name><param-value>true</param-value></init-param><!-- comet方式 --><!-- <init-param><param-name>activeReverseAjaxEnabled</param-name><param-value>true</param-value></init-param>--><!-- polling方式:在comet方式的基礎(chǔ)之上,再配置以下參數(shù) --><!-- <init-param><param-name>org.directwebremoting.extend.ServerLoadMonitor</param-name><param-value>org.directwebremoting.impl.PollingServerLoadMonitor</param-value></init-param>--><!-- 毫秒數(shù)。頁面默認的請求間隔時間是5秒 --><!-- <init-param><param-name>disconnectedTime</param-name><param-value>60000</param-value> </init-param>--><load-on-startup>1</load-on-startup> </servlet><servlet-mapping><servlet-name>dwr-invoker</servlet-name><url-pattern>/dwr/*</url-pattern> </servlet-mapping>而我使用的comet方式,所以我在web.xml中加入了
<servlet><servlet-name>dwr</servlet-name><servlet-class>org.directwebremoting.spring.DwrSpringServlet</servlet-class> <!-- spring 配置dwr --><init-param><param-name>debug</param-name><param-value>true</param-value></init-param><!-- 設(shè)置是否允許使用dwr推送技術(shù) --><init-param><param-name>activeReverseAjaxEnabled</param-name> <param-value>true</param-value> </init-param><init-param><param-name>maxWaitAfterWrite</param-name><param-value>3000</param-value></init-param><load-on-startup>1</load-on-startup></servlet>
要想實現(xiàn)精確推送到特定的頁面,要把想要推送的頁面上標識一個Id,dwr推送時過濾這個Id,沒有標記Id或Id不一致的頁面則不推送。
package com.cqut.service.dwrPush;import org.directwebremoting.ScriptSession; import org.directwebremoting.WebContextFactory; import org.directwebremoting.annotations.RemoteMethod; import org.directwebremoting.annotations.RemoteProxy; import org.springframework.stereotype.Controller;@Controller @RemoteProxy public class RecipientInitService {//設(shè)置接收的頁面的Id,用于精確推送@RemoteMethodpublic void initCode(String recipientCode){ScriptSession scriptSession = WebContextFactory.get().getScriptSession();scriptSession.setAttribute("recipientCode", recipientCode); //recipientCode是自己為標記起的名字} }
然后加入推送輔助類,根據(jù)頁面的標記進行精確推送
package com.cqut.service.dwrPush;import java.util.Collection;import org.directwebremoting.Browser; import org.directwebremoting.ScriptBuffer; import org.directwebremoting.ScriptSession; import org.directwebremoting.ScriptSessionFilter; import org.directwebremoting.annotations.RemoteMethod; import org.directwebremoting.annotations.RemoteProxy; import org.springframework.stereotype.Controller;@Controller @RemoteProxy public class PushService {/*** 推送信息到特定的頁面* @param code 推送到的頁面 recipientCode* @param functionName 前臺調(diào)用 的JavaScript方法* @param args 前臺調(diào)用 的JavaScript方法的參數(shù)*/@RemoteMethod public void pushMsg(final String code,final String functionName,final Object... args){//定義過濾器ScriptSessionFilter filter = new ScriptSessionFilter() {public boolean match(ScriptSession session) {if (session.getAttribute("recipientCode") == null) {return false;} else {return (session.getAttribute("recipientCode")).equals(code);}}};//執(zhí)行推送pushMsgOnFilter(filter, functionName, args);}/*** 根據(jù)傳遞過來的過濾器參數(shù)進行頁面的推送* @param filter 過濾器* @param functionName 前臺javascripg要執(zhí)行的方法* @param args 前臺javascripg要執(zhí)行方法的參數(shù)*/public void pushMsgOnFilter(ScriptSessionFilter filter,final String functionName,final Object... args){Runnable run = new Runnable(){private ScriptBuffer script = new ScriptBuffer();public void run() {//設(shè)置要調(diào)用的 js及參數(shù)script.appendCall(functionName , args);//得到所有ScriptSessionCollection<ScriptSession> sessions = Browser.getTargetSessions();//遍歷每一個ScriptSessionfor (ScriptSession scriptSession : sessions){scriptSession.addScript(script);}}};Browser.withAllSessionsFiltered(filter,run); //使用過濾器實現(xiàn)推送} }
在前臺需要推送的頁面加入下面javascripg代碼
//設(shè)置頁面建立長連接 dwr.engine.setActiveReverseAjax(true); dwr.engine.setNotifyServerOnPageUnload(true); //設(shè)置頁面標記Id RecipientInitService.initCode("manager");
在后臺要推送的頁面,使用輔助類實現(xiàn)推送
dwrPushService.pushMsg( "mamanger","test", "123"); //manager是頁面標記,test是js方法,124是test方法的參數(shù)
推送實現(xiàn)完成
轉(zhuǎn)載于:https://www.cnblogs.com/bin1991/p/3636640.html
總結(jié)
- 上一篇: 数据库的增删改查和使用流程
- 下一篇: 浅谈大端和小端