DWR框架的初次使用及经验总结

DWR的宣传语是 “ Easy Ajax For Java”。

需求是这样的--后端定时接受服务器发送过来的信息。并把信息每隔五秒推送一次到前端实现页面局部刷新功能

AJAX可是实现前端异步发送请求到后端,拿取数据,并实现页面局部刷新的功能!

Ajax有一个很大的缺陷就是“无法满足传统桌面系统的需求——服务器端需要向客户端主动发送消息”。服务端推送技术的应用场景有很多!

DWR框架技术可以实现即时推送后端数据到客户端。

因为这个功能。我是帮别人做的。他用的框就是springmvc.也没用maven做管理。所以步骤如下:

1:引入jar包

dwr.jar  commons-logging-1.1.3.jar  quartz-2.3.0.jar  quartz-jobs-2.2.3.jar  spring-context-support-4.0.0.RELEASE.jar

2:配置文件配置相关DWR框架支持

web.xml配置。配置类似DispatchServlet的配置

<!-- dwr配置信息start -->
        <servlet>
        <!-- 指定DWR核心Servlet的名字 -->
        <servlet-name>dwr</servlet-name>
        <!-- 指定DWR核心Servlet的实现类 -->
        <servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
        <!-- 指定DWR核心Servlet处于调试状态 -->
        <init-param>
            <param-name>debug</param-name>
            <param-value>true</param-value>
        </init-param>
        <!-- 设置使用反向Ajax技术 -->
        <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>maxWaitAfterWrite</param-name>
            <param-value>60</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <!-- 指定核心Servlet的URL映射 -->
    <servlet-mapping>
        <servlet-name>dwr</servlet-name>
        <url-pattern>/dwr/*</url-pattern>
    </servlet-mapping>
    <!-- dwr配置信息end -->

    <!--对静态文件和页面不拦截-->

    <servlet-mapping>       
        <servlet-name>default</servlet-name>      
        <url-pattern>*.html</url-pattern>     
    </servlet-mapping>
    <servlet-mapping>      
        <servlet-name>default</servlet-name>   
        <url-pattern>*.js</url-pattern>   
    </servlet-mapping>   
    <servlet-mapping>       
        <servlet-name>default</servlet-name>      
        <url-pattern>*.css</url-pattern>     
    </servlet-mapping>

dwr.xml文件配置。放在和web.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>
    <!-- DWR可以创建和转换的类 -->
  <allow>
        <!-- 指定用哪种创造器 -->
       <create javascript="Message" creator="new" scope="application"><!-- application -->  

        <include method="addMessage"/>   <!--只对前端开房addMessage方法-->
        <param name="class" value="com.zukai.test.Message"></param>  
    </create> 
  </allow>

</dwr>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	    xmlns:context="http://www.springframework.org/schema/context"
	    xmlns:aop="http://www.springframework.org/schema/aop"
	    xmlns:tx="http://www.springframework.org/schema/tx"
	    xsi:schemaLocation="http://www.springframework.org/schema/beans
	        http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
	        http://www.springframework.org/schema/context
	       http://www.springframework.org/schema/context/spring-context-4.2.xsd
	       http://www.springframework.org/schema/aop
	       http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
	       http://www.springframework.org/schema/tx
	       http://www.springframework.org/schema/tx/spring-tx-4.2.xsd">
	<!-- <bean id="udpClient" class="com.zukai.connection.udp.UDPClient" init-method="recv"/> -->
	
	<!-- 业务实体 -->
    <bean name="quartzTest" class="com.zukai.test.QuartzTest" init-method="recv"/>
    <!-- 定义定时任务 -->
    <bean id="quartzTestJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <property name="targetObject" ref="quartzTest"></property><!-- 目标对象 -->
        <property name="targetMethod" value="pushRefresh"></property><!-- 目标方法 -->
        <property name="concurrent" value="false"></property><!-- 多job并发设置 -->
    </bean>
    

	<!-- 定义触发器 -->
    <bean id="quartzTestTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
        <property name="jobDetail" ref="quartzTestJob"/>
        <!--延时多少秒后执行,这里不延时 0秒后运行 -->
        <property name="startDelay" value="0" />
        <!-- 每隔5秒重复运行 -->
        <property name="repeatInterval" value="5000" />
    </bean>
    
	<!-- 定义定时调度 -->
    <bean name="quartzScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <property name="triggers">
            <list>
                <ref bean="quartzTestTrigger" />
            </list>
        </property>
    </bean>


			

</beans>

上面是引入定时任务的配置信息。每5秒执行一次冲服务器获取数据信息。代码如下:

package com.zukai.test;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

/**
 *author:liyy
 *date:2018年10月9日
 *描述信息:
 */
@Component
public class QuartzTest {
	
	public static Logger logger = LoggerFactory.getLogger(QuartzTest.class);
	
	public static Map<String,Object> mapCache = new ConcurrentHashMap<>();
	
	public static DatagramSocket ds = null;
	
    //每隔五秒調用一次,获取数据推送到页面
    public void pushRefresh() throws IOException, InterruptedException {
    	Message mg = new Message();
    	String message = null;
    	if(mapCache.containsKey("message")){
    		message = (String)mapCache.get("message");
        	mg.addMessage("admin", message+"瓦"+","+message+"度");
    	}
    }
    
 	//获取UDP服务器发送的数据,并存储到mapCache里面。
    public void recv(){
    	new Thread(new ReceiveThread()).start();
    }
    
    public void schedule(){
    	 //注意这里就是可以进行数据库的查询操作,可以将查询需要推送的信息放到第二个参数,第一个参数自然是我们要指定推送的表示用户
    	Message mg = new Message();
	    for(int i=0;i<100;i++){
	    	try {
				Thread.sleep(5000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	    	mg.addMessage("admin", i+1000+"瓦"+","+i+30+"度");
	    }
	    
    }
    
    private String bytesToHex(byte[] bytes, int begin, int end) {
        StringBuilder hexBuilder = new StringBuilder(2 * (end - begin));
        for (int i = begin; i < end; i++) {
            hexBuilder.append(Character.forDigit((bytes[i] & 0xF0) >> 4, 16)); // 转化高四位
            hexBuilder.append(Character.forDigit((bytes[i] & 0x0F), 16)); // 转化低四位
        }
        return hexBuilder.toString().toUpperCase();
    }
    
    public static Long HexToDecimalism(String hexNum){
    	Long decNum = Long.parseLong(hexNum,16);
    	return decNum;
    }
    
    class ReceiveThread implements Runnable{

		@Override
		public void run() {
			// TODO Auto-generated method stub
			logger.info("接受数据开始......");
	        //DatagramSocket ds = null;
	        try {
	        	if(ds==null){
	        		ds = new DatagramSocket(2000);// UDP通信类 2000为端口号
	        	}
	        } catch (SocketException e1) {
	            // prompt("本地接收端口已被使用");
	            logger.error("本地接收端口已被使用");
	            System.exit(0);	
	        }
	        while (true) {			
	        	byte[] buf = new byte[1024];			
	        	DatagramPacket dp = new DatagramPacket(buf, buf.length); // 接收数据	
	        	try {
	        		ds.receive(dp);
					String ip = dp.getAddress().getHostAddress();// ip地址			
		        	int port = dp.getPort();// 返回接收或发送该数据报文的远程主机端口号。			
		        	String text = bytesToHex(dp.getData(),0,dp.getLength());			
		        	//String text = new String(dp.getData(), 0, dp.getLength());
		        	// 获取的串口数据			
		        	if (text.equals("exit")) {				
		        		System.out.println(ip + "退出会话......");				
		        		break;			
		    		}			
		        	System.out.println(ip + ":" + port + "===>me " + text);					
		        	mapCache.put("message", text);	
				}catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}finally{
					//ds.close();
				}
	        }	
		}
    	
    }

}

前端页面定时获取数据。刷新

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		
		<script type="text/javascript" src="js/engine.js"></script>
		<script type="text/javascript" src="js/util.js"></script>
		<script type="text/javascript" src="js/Message.js"></script>
		<script type="text/javascript" src="js/jquery-1.4.2.js"></script>
		<script type="text/javascript">
		    var chatlog = "";
		    //发送信息
		    /* function sendMessage() {
		        var message = $("#message").val();
		        var user = $("#user").val();
		        Message.addMessage(user, message);
		    } */
		    //接收信息
		    function receiveMessages(messages) {
		        var lastMessage =  messages;
		        /* chatlog = "<div>" + lastMessage + "</div>" + chatlog; */
		        electricity = lastMessage.split(",")[0];
		        temperature = lastMessage.split(",")[1];
		        dwr.util.setValue("showElectricity",electricity, {
		            escapeHtml : false
		        });
		        
		        dwr.util.setValue("showTemperature", temperature, {
		            escapeHtml : false
		        });
		    }
		
		    //读取name值作为推送的唯一标示
		    function onPageLoad(){
		        var userId = getQueryString("name");
		        /* $("#myName").html(userId); */
		        Message.onPageLoad(userId);
		     }
		
		    //获取url中的参数
		    function getQueryString(name) {
		        var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
		        var r = window.location.search.substr(1).match(reg);
		        if (r != null) return unescape(r[2]); 
		        return null;
		    }
		    //一上来就加载onPageLoad()方法,将读取的name作为唯一标识,这里不一定要从url中取出name作为标识符,只要是该页面唯一的数据都可以是标识符
		    $(document).ready(function(){
		        dwr.engine.setActiveReverseAjax(true);//使用ajax反向代理
		        dwr.engine.setNotifyServerOnPageUnload(true);//服务启动直接加载
		        onPageLoad();
	        }); 
		
		</script>
	</head>
	<body>
		 <!-- 我是<span id="myName" style="color:red"></span><br/>
	         推送给下面这位user<br/>    
	    user:<br/>
	    <input id="user" type="text" /><br/>
	    	推送信息为:<br/>
	    <input id="message" type="text" value="hey" />
	    <input type="button" value="send" onclick="sendMessage()" />
	    <br> -->
	    <!-- <div id="list"></div> -->
	    <div  style="height: 760px;width: 100%;">
			<div style="height: 180px;width: 100%;text-align:center;">
				电流:<input id="showElectricity" type="text"  value="" style="width: 440px;height: 60px;">
			</div>
			<div style="height: 180px;width: 100%;text-align: center;">
				温度:<input id="showTemperature" type="text"  value="" style="width: 440px;height: 60px;">
			</div>
		</div>
	</body>
</html>
package com.zukai.test;
/**
 *author:liyy
 *date:2018年10月9日
 *描述信息:
 */

import java.util.Collection;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpSession;

import org.directwebremoting.Browser;
import org.directwebremoting.ScriptBuffer;
import org.directwebremoting.ScriptSession;
import org.directwebremoting.ScriptSessionFilter;
import org.directwebremoting.WebContextFactory;

public class Message{

    public void addMessage(String userid, String message) {
        final String userId = userid;
        final String autoMessage = message;
        System.out.println("To:" + userid + ",Msg:" + message);
        Browser.withAllSessionsFiltered(new ScriptSessionFilter() {
            public boolean match(ScriptSession session) {
                if (session.getAttribute("name") == null)
                    return false;
                else
                    return (session.getAttribute("name")).equals(userId);
                }
            }, new Runnable() {
                private ScriptBuffer script = new ScriptBuffer();

                public void run() {
                    script.appendCall("receiveMessages", autoMessage);
                    Collection<ScriptSession> sessions = Browser
                            .getTargetSessions();
                    for (ScriptSession scriptSession : sessions) {
                        if(scriptSession.getAttribute("name").equals(userId)){
                            scriptSession.addScript(script);
                            break;
                        }
                    }
                }
            });
    }
    
    //页面加载直接执行该方法
    public void onPageLoad(String name) {
        HttpSession session = WebContextFactory.get()
                .getSession();
        session.setAttribute("name", name);
        WebContextFactory.get().getScriptSession().setAttribute("name", name);

    }

}


 

猜你喜欢

转载自blog.csdn.net/liyingying111111/article/details/83009707