首页 > 技术文章 > DWR 逆ajax 实现网页聊天

bigsaltfish 2016-06-23 16:56 原文

1.添加jar包

  dwr的需要的jar很少,只有一个核心的dwr.jar,依赖一个commons-logging.jar

  附下载地址,戳我

2.配置xml文件

  2.1 web.xml的配置

    

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" 
	xmlns="http://java.sun.com/xml/ns/j2ee" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
	http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
	<servlet>
        <servlet-name>dwr-invoker</servlet-name>
        <servlet-class>
            org.directwebremoting.servlet.DwrServlet
        </servlet-class>

        <init-param>
            <param-name>crossDomainSessionSecurity</param-name>
               <param-value>false</param-value>
            </init-param>
        <init-param>
          <param-name>allowScriptTagRemoting</param-name>
          <param-value>true</param-value>
        </init-param>

        <init-param>
          <param-name>classes</param-name>
          <param-value>java.lang.Object</param-value>
        </init-param>

<!-- comet方式 --> 
        <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>3000</param-value>
        </init-param>

        <init-param>
            <param-name>debug</param-name>
            <param-value>true</param-value>
        </init-param>

        <init-param>
            <param-name>logLevel</param-name>
            <param-value>WARN</param-value>
        </init-param>

    </servlet>

<!-- 拦截/dwr/的请求,给org.directwebremoting.servlet.DwrServlet处理 -->
	<servlet-mapping>
		<servlet-name>dwr-invoker</servlet-name>
		<url-pattern>/dwr/*</url-pattern>
	</servlet-mapping>
	
	<servlet>
		<servlet-name>LoginAction</servlet-name>
		<servlet-class>com.zy.servlet.LoginServlet</servlet-class>
	</servlet>

	<servlet-mapping>
		<servlet-name>LoginAction</servlet-name>
		<url-pattern>/login.do</url-pattern>
	</servlet-mapping>
	
	<welcome-file-list>
	  <welcome-file>login.jsp</welcome-file>
	</welcome-file-list>
</web-app>
  2.2dwr.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>
<!-- Reverse Ajax Stock push Demo Config
	<create creator="new" javascript="StocksPusher">
	<param name="class" value="com.test.dwr.servlet.Test"/>
	</create>

	<convert converter="bean" match="com.test.dwr.bean.Message"> 
		<param name="include" value="id,context" />
	</convert>
	 -->
    <create creator="new" javascript="bindUser">
       <param name="class" value="com.zy.utils.BindUserUtil"/>
    </create>

     <create creator="new" javascript="sendMessage">
       <param name="class" value="com.zy.utils.SendMessageUtil"/>
    </create>
	
</allow>
</dwr>
  dwr.xml的javascript的值,就是我们在jsp中的调用类的引用


3.前端页面

    3.1登录界面(存入id)

<%@ 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>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>登录页</title>
</head>
<body>
	<form action="login.do" method="post">
		<table>
			<tr>
				<td>id:</td>
				<td><input type="text" name="id"></td>
			</tr>
			<tr>
				<td>name:</td>
				<td><input type="text" name="name"></td>
			</tr>
			<tr>
				<td><input type="submit" value="登录"></td>
				<td></td>
			</tr>
		</table>
	</form>
</body>
</html>

  3.2 聊天界面(接收信息)

<%@ 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>
	<%
		String path = request.getContextPath();
		String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
	%>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
	<title>这是聊天界面</title>
	<!-- <meta http-equiv="pragma" content="no-cache">  
    <meta http-equiv="cache-control" content="no-cache">  
    <meta http-equiv="expires" content="0">      
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">  
    <meta http-equiv="description" content="This is my page"> -->
    
	<script type="text/javascript" src="<%=path %>/js/jquery-1.5.1.js"></script>
	<script type="text/javascript" src="<%=path %>/dwr/engine.js"></script>
	<script type="text/javascript" src="<%=path %>/dwr/util.js"></script>
	<script type="text/javascript" src="<%=path %>/dwr/interface/bindUser.js"></script>
	
	<script type="text/javascript">
		//通过该方法与后台交互,确保推送时能找到指定用户
	    function bindUserPage(){
	       var userId = "${user.id}";
	       bindUser.bindUserByUserId(userId);
	     }
	    //推送信息
		 function receiveMessage(autoMessage){
			$("#messageDiv").append(autoMessage + "<br>");
			alert(111);
			console.log(autoMessage);
		}
	</script>
</head>
<body onload="bindUserPage();dwr.engine.setActiveReverseAjax(true);dwr.engine.setNotifyServerOnPageUnload(true);">
	<div id="messageDiv">
		
	</div>
</body>
</html>

   3.3消息发送界面

<%@ 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>
	<%
		String path = request.getContextPath();
		String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
	%>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
	<title>这是消息发送界面</title>
	<!-- <meta http-equiv="pragma" content="no-cache">  
    <meta http-equiv="cache-control" content="no-cache">  
    <meta http-equiv="expires" content="0">      
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">  
    <meta http-equiv="description" content="This is my page"> -->
    
	<script type="text/javascript" src="<%=path %>/js/jquery-1.5.1.js"></script>
	<script type="text/javascript" src="<%=path %>/dwr/engine.js"></script>
	<script type="text/javascript" src="<%=path %>/dwr/util.js"></script>
	<script type="text/javascript" src="<%=path %>/dwr/interface/sendMessage.js"></script>
	
	<script type="text/javascript">
		$(document).ready(function(){
			$("#sendMessage").click(function(){
				var userId = $("#userId").val();
				var message = $("#message").val();
				
				console.log("message:"+message);
				sendMessage.sendMessage(userId,message);
			});
		});
	</script>
</head>
<body>
	接收者的id:<input type="text" id="userId"><br>
	<textarea rows="10" cols="10" id="message"></textarea><br>
	<input type="button" value="发送" id="sendMessage">
</body>
</html>

4.后台的逻辑处理

   4.1登录的servlet

     
public class LoginServlet extends HttpServlet{
	private static final long serialVersionUID = -5216193301182504458L;

	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		this.doPost(request, response);
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		int id = Integer.valueOf(request.getParameter("id"));
		String username = request.getParameter("name");
		HttpSession session = request.getSession();
		User user = new User();
		user.setId(id);
		user.setName(username);

		session.setAttribute("user", user);
		response.sendRedirect("chat.jsp");
	}
}

   4.2 初始化scriptSession

public class BindUserUtil {

	public void bindUserByUserId(String userId) {
		ScriptSession scriptSession = WebContextFactory.get().getScriptSession();
		scriptSession.setAttribute(userId, userId);
		DwrInit dwrScriptSessionManagerUtil = new DwrInit();

		try {
			dwrScriptSessionManagerUtil.init();
			System.out.println("userId:" + userId + "绑定成功!!");
		} catch (ServletException e) {
			e.printStackTrace();
		}
	}

}

/**
 * 
 * Des:DWR的初始化,根据id和页面,绑定页面和用户
 * @author:zy
 * @version: 2016年6月23日上午11:19:17
 */
public class DwrInit extends DwrServlet{
	private static final long serialVersionUID = -7504612622407420071L;

	public void init() throws ServletException {

		Container container = ServerContextFactory.get().getContainer();
		ScriptSessionManager manager = container.getBean(ScriptSessionManager.class);
		ScriptSessionListener listener = new ScriptSessionListener() {
			public void sessionCreated(ScriptSessionEvent ev) {
				HttpSession session = WebContextFactory.get().getSession();
				String userId = ((User) session.getAttribute("user")).getId() + "";
				System.out.println("为userId用户创建了一条scriptSession!" + userId);
				ev.getSession().setAttribute("userId", userId);
			}

			public void sessionDestroyed(ScriptSessionEvent ev) {
				System.out.println("销毁了一条scriptSession");
			}
		};
		manager.addScriptSessionListener(listener);
	}

}


  4.3发送消息

public class SendMessageUtil {
	/**
	 * @Desc:
	 * @param userid  消息接收者id
	 * @param message 发送的具体消息
	 * @author:zy
	 * @version: 2016年6月23日 上午11:34:31
	 */
	public void sendMessage(String userid, String message) {

		final String userId = userid;
		final String autoMessage = message;
		Browser.withAllSessionsFiltered(new ScriptSessionFilter() {
			public boolean match(ScriptSession session) {
				if (session.getAttribute("userId") == null)
					return false;
				else
					return (session.getAttribute("userId")).equals(userId);
			}
		}, new Runnable() {
			private ScriptBuffer script = new ScriptBuffer();
			public void run() {
				script.appendCall("receiveMessage", autoMessage);
				System.out.println("autoMessage====>" + autoMessage);
				Collection<ScriptSession> sessions = Browser.getTargetSessions();

				for (ScriptSession scriptSession : sessions) {
					scriptSession.addScript(script);
				}
			}
		});
	}
}






项目代码下载,戳我


推荐阅读