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
dwr-invoker
org.directwebremoting.servlet.DwrServlet
调试DWR,发布系统时应将其设为false
debug
true
使用服务器推技术(反转AJAX)
activeReverseAjaxEnabled
true
initApplicationScopeCreatorsAtStartup
true
maxWaitAfterWrite
100
4
dwr-invoker
/dwr/*
这个参数DWR默认是false。如果选择true,我们可以通过http://localhost:port/app/dwr看到你部署的每个DWR class。并且可以测试java代码的每个方法是否运行正常。为了安全考虑,在正式环境下你一定把这个参数设为false。
2.使用dwr还要由一个dwr.xml配置文件
DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN" "http://getahead.org/dwr/dwr20.dtd">
二.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 users = new ArrayList();
/**
*更新在线用户列表
*
*@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", users, "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 sessions = new HashSet();
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) {
$('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+""+messages;
}
window.onload = init;//页面加载时
6. html代码
需要导入必须的js文件,在文本编辑时,我用了一个fckEditor文本编辑器,上网下一个就可以了,放在根目录下,本人美感欠缺,页面不太好看,请见谅!具体代码如下:
chat
昵称:
我要对
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?


微信扫码登录