日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

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

發(fā)布時(shí)間:2025/3/21 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 b/s模式下的即时通讯,使用ajax框架dwr实现 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

b/s模式下的即時(shí)通訊,使用ajax框架dwr實(shí)現(xiàn)

?

了解java的發(fā)展史可以知道,客戶端編程在基于瀏覽器的編程方面,以前的做法是用applet實(shí)現(xiàn)客戶端編程,在當(dāng)時(shí)算是流行的做法,但是隨著IE的不一致,尤其是微軟的不支持,

Applet沒(méi)有發(fā)展起來(lái),還有一個(gè)原因就是在瀏覽器中要下載java運(yùn)行時(shí)插件,這幾M的大小,對(duì)于以前網(wǎng)速就慢的網(wǎng)絡(luò),無(wú)疑斷送了它的性命。現(xiàn)在應(yīng)用與客戶端瀏覽器的技術(shù)主要為一些牛人自己開(kāi)發(fā)的插件,通過(guò)下載實(shí)現(xiàn)自己的功能?,F(xiàn)在最通用最新的做法是利用XmlHttpRequext,異步實(shí)現(xiàn)客戶端請(qǐng)求,也就是通常所說(shuō)的ajax(異步的JavaScript和xml)技術(shù),可以使用封裝好的dwr框架簡(jiǎn)化開(kāi)發(fā),另一種方式就是使用Flex技術(shù),就是Flash腳本編程,只是聽(tīng)說(shuō),自己還沒(méi)有用過(guò)。

?

自己寫(xiě)了一個(gè)使用ajax框架dwr實(shí)現(xiàn)簡(jiǎn)易的即時(shí)通信程序。

首先什么是dwr呢?DWR是一個(gè)框架,簡(jiǎn)單的說(shuō)就是能夠在javascript直接調(diào)用java方法,而不必去寫(xiě)一大堆的javascript代碼。它的實(shí)現(xiàn)是基于ajax的,可以實(shí)現(xiàn)無(wú)刷新效果。

一、?????????? dwr配置篇

1.web.xml

<servlet>

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

?????? <servlet-class>

?????????? org.directwebremoting.servlet.DwrServlet

?????? </servlet-class>

?????? <init-param>

?????????? <description>調(diào)試DWR,發(fā)布系統(tǒng)時(shí)應(yīng)將其設(shè)為false</description>

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

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

?????? </init-param>

?????? <init-param>

?????????? <description>使用服務(wù)器推技術(shù)(反轉(zhuǎn)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>

這個(gè)參數(shù)DWR默認(rèn)是false。如果選擇true,我們可以通過(guò)http://localhost:port/app/dwr看到你部署的每個(gè)DWR class。并且可以測(cè)試java代碼的每個(gè)方法是否運(yùn)行正常。為了安全考慮,在正式環(huán)境下你一定把這個(gè)參數(shù)設(shè)為false

2.使用dwr還要由一個(gè)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使用篇

實(shí)例:b/s模式下的即時(shí)通訊,使用ajax框架dwr實(shí)現(xiàn)

1.?????? 首先把dwr.jar包放在項(xiàng)目lib目錄下。

2.?????? 進(jìn)行上述web.xml相關(guān)配置,上述配置就是本實(shí)例的配置。

3.?????? 為實(shí)現(xiàn)功能寫(xiě)的javabean,可能還有servlet,但本實(shí)例沒(méi)有牽涉到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;

?

/**

?*處理聊天相關(guān)

?*

?*@authorlhq

?*

?*/

publicclass ChatManager {

?

??? /**保存當(dāng)前在線用戶列表*/

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

?

??? /**

??? ?*更新在線用戶列表

??? ?*

??? ?*@paramusername

??? ?*??????????? 待添加到列表的用戶名

??? ?*@paramflag

??? ?*??????????? 是添加用戶到列表,還是只獲得當(dāng)前列表

??? ?*@paramrequest

??? ?*@return用戶userid

??? ?*/

??? public String updateUsersList(String username, boolean flag,

?????????? HttpServletRequest request) {

?????? User user = null;

?????? if (flag) {

?????????? // 這里取會(huì)話(HttpSession)id為用戶id

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

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

?????????? // 保存用戶到列表

?????????? users.add(user);

?????????? // 將用戶id和頁(yè)面腳本session綁定

?????????? this.setScriptSessionFlag(user.getUserid());

?????? }

?????? // 獲得DWR上下文

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

?????? ServerContext sctx = ServerContextFactory.get(sc);

?????? // 獲得當(dāng)前瀏覽 index.jsp 頁(yè)面的所有腳本session

?????? Collection sessions = sctx

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

?????? System.out.println("session的記錄數(shù):" + sessions.size());

?????? // 消除不存在的頁(yè)面session

?????? System.out.println("session的記錄數(shù)(消除后):" + sessions.size());

?????? Util util = new Util(sessions);

?????? // 處理這些頁(yè)面中的一些元素

?????? util.removeAllOptions("users");

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

?????? util.removeAllOptions("receiver");

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

?????? if (!flag) {

?????????? returnnull;

?????? }

?????? return user.getUserid();

??? }

?

??? /**

??? ?*

??? ?*當(dāng)退出時(shí)更新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和頁(yè)面腳本session綁定

??? ?*

??? ?*@paramuserid

??? ?*/

??? publicvoid setScriptSessionFlag(String userid) {

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

????????????? userid);

??? }

?

??? /**

??? ?*根據(jù)用戶id獲得指定用戶的頁(yè)面腳本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;

??? }

?

??? /**

??? ?*發(fā)送消息

??? ?*

??? ?*@paramsender

??? ?*??????????? 發(fā)送者

??? ?*@paramreceiverid

??? ?*??????????? 接收者id

??? ?*@parammsg

??? ?*??????????? 消息內(nèi)容

??? ?*@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 + "說(shuō):" + msg + "/n").appendScript(");");

?????? session.addScript(script);

??? }

}

4.?????? 進(jìn)行dwr.xml相對(duì)于javabean的相關(guān)配置,及提供客戶端JavaScript腳本對(duì)于java方法的可見(jiàn)性。上述代碼及為本實(shí)例代碼。

5.?????? 客戶端javascript中調(diào)用

自定義一個(gè)chat.js文件,用來(lái)跟后臺(tái)進(jìn)行交互。代碼如下:

/**

?* 注冊(cè)

?*/

function register(button) {

???

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

?????? alert("請(qǐng)輸入昵稱");

?????? return;

??? }

?

??? /*相應(yīng)按鈕處理 */

??? $('username').disabled = true;

??? button.disabled = true;

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

??? $('send').disabled = false;

??? $('receiver').disabled = false;

??? $('send').disabled = false;

??? $('exit').disabled = false;

??? /*調(diào)用后臺(tái)ChatManager類的updateUsersList方法,并取得返回值元數(shù)據(jù)放在data*/

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

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

?????????? $('userid').value = data; //??? 把當(dāng)前sessionId放在隱藏表單

}

??? });

}

?

/**

?*初始化

?*/

function init() {

??? dwr.engine.setActiveReverseAjax(true); // 激活反轉(zhuǎn)

??? ChatManager.updateUsersList(null, false); //和上面那個(gè)方法一樣

}

function delUser(button) {

??? ChatManager.delUser(); //當(dāng)退出是調(diào)用,消除該在線用戶

/**

?*并對(duì)相應(yīng)按鈕進(jìn)行相應(yīng)處理

?*/

?

??? $('username').disabled = false;

??? $('register').disabled = false;

??? button.disabled=true;

??? $('receiver').disabled = true;

??? $('send').disabled = true;

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

}

/**

?* 當(dāng)發(fā)送信息是調(diào)用

?*/

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); //調(diào)用后臺(tái)方法

}

/**

*這是后臺(tái)推技術(shù)調(diào)用的方法,接受信息

*/

function receiveMessages(message) {

//取得聊天信息中文本

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

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

???

}

?

window.onload = init;//頁(yè)面加載時(shí)

?

6.?????? html代碼

需要導(dǎo)入必須的js文件,在文本編輯時(shí),我用了一個(gè)fckEditor文本編輯器,上網(wǎng)下一個(gè)就可以了,放在根目錄下,本人美感欠缺,頁(yè)面不太好看,請(qǐng)見(jiàn)諒!具體代碼如下:

<%@ 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="注冊(cè)" onclick="register(this);" id="register"/>

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

?????? <br />

?????? <br />

?????? 我要對(duì)

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

?????? </select>

?????? 說(shuō):

?????? <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="發(fā)送" 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>

好了,終于寫(xiě)完了,首先要說(shuō)明一下,本程序不是很完善,具體在:用戶只有點(diǎn)擊“退出”按鈕才可以實(shí)現(xiàn)把該在線人員刪除掉,可能利用js也可以實(shí)現(xiàn)關(guān)閉頁(yè)面也可以把該在線人員刪除掉,但是如果用戶刷新了,怎么辦呢???就是怎么記錄有效地scriptsession呢?有人說(shuō)用map保存。本人沒(méi)有試過(guò),還望高手指點(diǎn),不勝感激!!!

總結(jié)

以上是生活随笔為你收集整理的b/s模式下的即时通讯,使用ajax框架dwr实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。