b/s模式下的即时通讯,使用ajax框架dwr实现

前端之家收集整理的这篇文章主要介绍了b/s模式下的即时通讯,使用ajax框架dwr实现前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

b/s模式下的即时通讯,使用ajax框架dwr实现

了解java的发展史可以知道,客户端编程在基于浏览器的编程方面,以前的做法是用applet实现客户端编程,在当时算是流行的做法,但是随着IE的不一致,尤其是微软的不支持

Applet没有发展起来,还有一个原因就是在浏览器中要下载java运行时插件,这几M的大小,对于以前网速就慢的网络,无疑断送了它的性命。现在应用与客户端浏览器的技术主要为一些牛人自己开发的插件,通过下载实现自己的功能。现在最通用最新的做法是利用XmlHttpRequext,异步实现客户端请求,也就是通常所说的ajax(异步的JavaScript和xml)技术,可以使用封装好的dwr框架简化开发,另一种方式就是使用Flex技术,就是Flash脚本编程,只是听说,自己还没有用过。

自己写了一个使用ajax框架dwr实现简易的即时通信程序。

首先什么是dwr呢?DWR是一个框架,简单的说就是能够在javascript直接调用java方法,而不必去写一大堆的javascript代码。它的实现是基于ajax的,可以实现无刷新效果

一、 dwr配置篇

1.web.xml

<servlet>

<servlet-name>dwr-invoker</servlet-name>

<servlet-class>

org.directwebremoting.servlet.DwrServlet

</servlet-class>

<init-param>

<description>调试DWR,发布系统时应将其设为false</description>

<param-name>debug</param-name>

<param-value>true</param-value>

</init-param>

<init-param>

<description>使用服务器推技术(反转AJAX)</description>

<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>100</param-value>

</init-param>

<load-on-startup>4</load-on-startup>

</servlet>

<servlet-mapping>

<servlet-name>dwr-invoker</servlet-name>

<url-pattern>/dwr/*</url-pattern>

</servlet-mapping>

这个参数DWR默认是false。如果选择true,我们可以通过http://localhost:port/app/dwr看到你部署的每个DWR class。并且可以测试java代码的每个方法是否运行正常。为了安全考虑,在正式环境下你一定把这个参数设为false

2.使用dwr还要由一个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>

<convert converter="bean" match="com.lhq.User" />

<create creator="new" javascript="ChatManager">

<param name="class" value="com.lhq.ChatManager" />

</create>

</allow>

</dwr>

二.Dwr使用篇

实例:b/s模式下的即时通讯,使用ajax框架dwr实现

1. 首先把dwr.jar包放在项目lib目录下。

2. 进行上述web.xml相关配置,上述配置就是本实例的配置。

3. 为实现功能写的javabean,可能还有servlet,但本实例没有牵涉到servlet。代码如下:

package com.lhq;

import java.util.ArrayList;

import java.util.Collection;

import java.util.HashSet;

import java.util.Iterator;

import java.util.List;

import java.util.Map;

import javax.servlet.ServletContext;

import javax.servlet.http.HttpServletRequest;

import org.directwebremoting.ScriptBuffer;

import org.directwebremoting.ScriptSession;

import org.directwebremoting.ServerContext;

import org.directwebremoting.ServerContextFactory;

import org.directwebremoting.WebContextFactory;

import org.directwebremoting.proxy.dwr.Util;

/**

*处理聊天相关

*

*@authorlhq

*

*/

publicclass ChatManager {

/**保存当前在线用户列表*/

publicstatic List<User> users = new ArrayList<User>();

/**

*更新在线用户列表

*

*@paramusername

* 添加到列表的用户名

*@paramflag

* 添加用户到列表,还是只获得当前列表

*@paramrequest

*@return用户userid

*/

public String updateUsersList(String username,boolean flag,

HttpServletRequest request) {

User user = null;

if (flag) {

// 这里取会话(HttpSession)id用户id

System.out.println("aauserid:" + request.getSession().getId());

user = new User(request.getSession().getId(),username);

// 保存用户到列表

users.add(user);

// 用户id页面脚本session绑定

this.setScriptSessionFlag(user.getUserid());

}

// 获得DWR上下文

ServletContext sc = request.getSession().getServletContext();

ServerContext sctx = ServerContextFactory.get(sc);

// 获得当前浏览 index.jsp 页面的所有脚本session

Collection sessions = sctx

.getScriptSessionsByPage("/BalanceCenter/index.jsp");

System.out.println("session的记录数:" + sessions.size());

// 消除不存在的页面session

System.out.println("session的记录数(消除后):" + sessions.size());

Util util = new Util(sessions);

// 处理这些页面中的一些元素

util.removeAllOptions("users");

util.addOptions("users",users,"username");

util.removeAllOptions("receiver");

util.addOptions("receiver","userid", "username");

if (!flag) {

returnnull;

}

return user.getUserid();

}

/**

*

*退出时更新user

*

*

*/

publicvoid delUser(HttpServletRequest request) {

String userid = request.getSession().getId();// userid相等,呵呵

System.out.println("userIdaa:" + userid);

Iterator it = users.iterator();

while (it.hasNext()) {

User user = (User) it.next();

System.out.println(user.getUsername());

System.out.println("userId:" + user.getUserid());

if (user.getUserid().equals(userid)) {

users.remove(user);

break;

}

}

updateUsersList(null,false,request) ;

}

/**

*用户id页面脚本session绑定

*

*@paramuserid

*/

publicvoid setScriptSessionFlag(String userid) {

WebContextFactory.get().getScriptSession().setAttribute("userid",

userid);

}

/**

*根据用户id获得指定用户页面脚本session

*

*@paramuserid

*@paramrequest

*@return

*/

@SuppressWarnings("unchecked")

public ScriptSession getScriptSession(String userid,

HttpServletRequest request) {

ScriptSession scriptSessions = null;

Collection<ScriptSession> sessions = new HashSet<ScriptSession>();

sessions.addAll(ServerContextFactory.get(

request.getSession().getServletContext())

.getScriptSessionsByPage("/BalanceCenter/index.jsp"));

for (ScriptSession session : sessions) {

String xuserid = (String) session.getAttribute("userid");

if (xuserid != null && xuserid.equals(userid)) {

scriptSessions = session;

}

}

return scriptSessions;

}

/**

*发送消息

*

*@paramsender

* 发送者

*@paramreceiverid

* 接收者id

*@parammsg

* 消息内容

*@paramrequest

*/

publicvoid send(String sender,String receiverid,String msg,

HttpServletRequest request) {

ScriptSession session = this.getScriptSession(receiverid,request);

Util util = new Util(session);

util.setStyle("showMessage","display", "");

ScriptBuffer script = new ScriptBuffer();

script.appendScript("receiveMessages(").appendData(

sender + "说:" + msg + "/n").appendScript(");");

session.addScript(script);

}

}

4. 进行dwr.xml相对于javabean的相关配置,及提供客户端JavaScript脚本对于java方法的可见性。上述代码及为本实例代码

5. 客户端javascript调用

自定义一个chat.js文件,用来跟后台进行交互。代码如下:

/**

* 注册

*/

function register(button) {

if ($('username').value == "" || $('username').value.length <= 0) {

alert("请输入昵称");

return;

}

/*相应按钮处理 */

$('username').disabled = true;

button.disabled = true;

//$('message').disabled = false;

$('send').disabled = false;

$('receiver').disabled = false;

$('send').disabled = false;

$('exit').disabled = false;

/*调用后台ChatManager类的updateUsersList方法,并取得返回值元数据放在data*/

ChatManager.updateUsersList($('username').value,true, function(data) {

if (data != null && data.length > 0) {

$('userid').value = data; // 把当前sessionId放在隐藏表单

}

});

}

/**

*初始化

*/

function init() {

dwr.engine.setActiveReverseAjax(true); // 激活反转

ChatManager.updateUsersList(null,false); //和上面那个方法一样

}

function delUser(button) {

ChatManager.delUser(); //退出调用,消除该在线用户

/**

*并对相应按钮进行相应处理

*/

$('username').disabled = false;

$('register').disabled = false;

button.disabled=true;

$('receiver').disabled = true;

$('send').disabled = true;

$('areaMessage').innerHTML = "";

}

/**

* 当发送信息是调用

*/

function send() {

var sender = dwr.util.getValue('username'); //取得该用户的名字

var receiver = dwr.util.getValue('receiver'); // 取得接收者

var msg = FCKeditorAPI.GetInstance("message").EditorDocument.body.innerHTML; // 取得文本编辑器的文本

ChatManager.send(sender,receiver,msg); //调用后台方法

}

/**

*这是后台推技术调用方法,接受信息

*/

function receiveMessages(message) {

//取得聊天信息中文

var messages=document.getElementById("areaMessage").innerHTML;

document.getElementById("areaMessage").innerHTML=message+"<hr/>"+messages;

}

window.onload = init;//页面加载时

6. HTML代码

需要导入必须的js文件,在文本编辑时,我用了一个fckEditor文本编辑器,上网下一个就可以了,放在根目录下,本人美感欠缺,页面不太好看,请见谅!具体代码如下:

<%@ page language="java" pageEncoding="GBK"%>

<% String context=request.getContextPath();

pageContext.setAttribute("ctx",context);

%>

<html>

<head>

<title>chat</title>

<Meta http-equiv="pragma" content="no-cache">

<Meta http-equiv="cache-control" content="no-cache">

<Meta http-equiv="expires" content="0">

<script type='text/javascript' src='/BalanceCenter/dwr/interface/ChatManager.js'></script>

<script type='text/javascript' src='/BalanceCenter/dwr/engine.js'></script>

<script type='text/javascript' src='/BalanceCenter/dwr/util.js'></script>

<script type="text/javascript" src="/BalanceCenter/chat.js"></script>

<script type="text/javascript" src="${ctx}/fckeditor/fckeditor.js"></script>

</head>

<body>

<input type="hidden" name="userid" />

<br>

昵称:

<input type="text" name="username" id="username" />

<input type="button" value="注册" onclick="register(this);" id="register"/>

<input type="button" value="退出" onclick="delUser(this);" id="exit"/>

<br />

<br />

我要对

<select name="receiver" id="receiver" disabled=true" >

</select>

:

<script type="text/javascript">

var oFCKeditor = new FCKeditor("message");

oFCKeditor.BasePath = '${ctx}/fckeditor/' ;

oFCKeditor.Height = 300 ;

oFCKeditor.ToolbarSet = 'Default';

oFCKeditor.Create() ;

</script>

<input type="button" value="发送" id="send" name="send" disabled="true"

onclick="send();" />

<br />

<br />

在线用户列表:

<ul id="users">

</ul>

<div id="showMessage" style="display: none">

<div id="areaMessage" style="position:absolute;

width:600px;

height:300px;

z-index:1;

border:solid;

overflow:auto;

">

</div>

</div>

</body>

</html>

好了,终于写完了,首先要说明一下,本程序不是很完善,具体在:用户只有点击“退出”按钮才可以实现把该在线人员删除掉,可能利用js也可以实现关闭页面也可以把该在线人员删除掉,但是如果用户刷新了,怎么办呢???就是怎么记录有效地scriptsession呢?有人说用map保存。本人没有试过,还望高手指点,不胜感激!!!

原文链接:https://www.f2er.com/ajax/163809.html

猜你在找的Ajax相关文章