上一篇日志利用推送源周期性地向订阅了某一事件的所有网页端推送信息,但怎么实现向特定的某一个用户推送信息呢,想象一个网络聊天室,怎么向单独的一个好友私聊呢。问题的关键就是那个SessionID,Pushlet默认是用java.rmi.server.UID参数的随机字符串作为会话标志,这就造成我们没法跟一个特点的用户对应上,也就是说客户必须在joinListen的时候提供一个他的ID,就像登陆qq时,输入用户名一样。
好了,这里就列出怎么修改相关代码,实现上述功能。
同样,首先用MyEclipse新建一个web工程,我这里命名为PushletTest2。不同的是,我们不引用pushlet.jar包了,因为我们要更改源码,在下载pushlet的时候里面就包含源代码了,最外层是nl包,加入我的工程的src里。好了,加进去之后会报错,将log4j.jar加入引用就好了。。之后,同样别忘了把pushlet.properties和sources.properties加入WebRoot/WEN-INF下。工程结构如下:

FirPush.java是自己写的一个触发推送动作的类,它是一个servlet,请求该servlet就触发向特定的用户推送信息的动作(当然,怎么触发推送动作还有很多种形式)。
web.xml代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<servlet-name>pushlet</servlet-name>
<servlet-class>nl.justobjects.pushlet.servlet.Pushlet</servlet-class>
<load-on-startup>3</load-on-startup>
</servlet>
<servlet>
<servlet-name>FirePush</servlet-name>
<servlet-class>com.mysrc.FirePush</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>pushlet</servlet-name>
<url-pattern>/pushlet.srv</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>FirePush</servlet-name>
<url-pattern>/FirePush</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
Ok,接下来就是要进行修改了,首先打开ajax-pushlet-client.js。PL对象,在它的最开始添加一个属性userId:'', ,因为分析ajax-pushlet-client.js之后会发现,所有的请求都是get方式,也就是说是将请求参数添加到url里的,我们要做的是在进行join请求的时候将userId加到url上。找到PL的_doRequest,它是一个函数,所有的请求都是通过调用它发出的,找到var url = PL.pushletURL + '?p_event=' + anEvent;这一行,这儿就是在构造请求参数,在它的后面加入代码:
if (anEvent == 'join' || anEvent == 'join-listen') { url = url + '&userId=' + PL.userId;
}
好了,ajax-pushlet-client.js的修改就完成了。
接下来是test.html:
<html>
<head>
<script type="text/javascript" src="ajax-pushlet-client.js"></script>
<script type="text/javascript">
PL.userId='piero';
PL._init();
PL.joinListen('myevent1');
function onData(event) {
alert(event.get("key1"));
}
</script>
</head>
<body>
This is pushlet test page....<br>
</body>
</html>
然后就是修改pushlet的java源代码,找到nl.justobjects.pushlet.core包下的SessionManager类,将它的createSession方法改成:
public Session createSession(Event anEvent) throws PushletException {
// Trivial
//return Session.create(createSessionId());
return Session.create(anEvent.getField("userId", "visitor"));
}
这儿就使得建立的session的id是发送过来的userId,而不是一个随机字符串。getField的第二个参数是当得不到请求参数userId的值的时候设定的默认值。
好了,所有的准备工作都完成了,接下来就是通过userId给特点的用户推送信息了。
FirePush.java代码如下:
package com.mysrc;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import nl.justobjects.pushlet.core.Dispatcher;
import nl.justobjects.pushlet.core.Event;
import nl.justobjects.pushlet.core.SessionManager;
public class FirePush extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
myUnicast();
//myMulticast();
//myBroadcast();
}
private void myUnicast()
{
if(SessionManager.getInstance().hasSession("piero")){
Event event = Event.createDataEvent("myevent1");
event.setField("key1", "houhou_yesttttt....");
Dispatcher.getInstance().unicast(event,"piero"); //向ID为piero的用户推送
System.out.println("success....");
}
else {
System.out.println("piero do not login....%%%%%%%%%%%%");
}
}
private void myMulticast()
{
Event event = Event.createDataEvent("myevent1");
event.setField("key1", "houhou....");
Dispatcher.getInstance().multicast(event); //向所有和myevent1名称匹配的事件推送
System.out.println("wa success....");
}
private void myBroadcast()
{
Event event = Event.createDataEvent("myevent1"); //向所有的事件推送,不要求和这儿的myevent1名称匹配
event.setField("key1", "dig hole....");
Dispatcher.getInstance().broadcast(event);
System.out.println("asw success....");
}
}
这儿主要利用了dispatcher的unicat/multicat/broadcast方法。
好了,值得一提的是在ajax-pushlet-client.js有publish方法,也就是上面提到的触发信息推送动作,其实完全可以在前端调用这个js的publish函数向订阅了某事件的所有网页推送信息。test2.html代码如下:
<html>
<head>
<script type="text/javascript" src="ajax-pushlet-client.js"></script>
<script type="text/javascript">
PL.userId='juvenh';
PL._init();
PL.joinListen('event223');
function onData(event) {
alert(event.get("eventVal"));
}
function sendnews(){
//PL.publish("myevent1","key1=dlut&ba=ls");
p_publish('myevent1', 'key1', 'dlut', 'ba', 'ls');
}
</script>
</head>
<body>
This is my JSP page. <br>
<input type = "button" value="发消息" onclick="sendnews()"/>
</body>
</html>
上面代码中的PL.publish和p_publish完全等效,查看p_publish的代码,其实也是构造请求url。这儿的publish方法只能向订阅某一事件的所有网页推送消息,也即等同于multicast方法,无法向某一个特定的用户推送,解决方法还是向上面那样修改pushlet的java源代码,在nl.justobjects.pushlet.core包下的Controller.java中的protected void doPublish(Command aCommand);函数,看一下就会发现,这儿就是调用了dispacher的multicast函数,这儿改成unicast,前提是上面的js的publish里提供了userId。

- 大小: 11.4 KB
分享到:
相关推荐
在这个"Pushlet后台往jsp前台推送消息实例"中,我们将深入探讨Pushlet的工作原理以及如何在实际项目中运用。 Pushlet是Java开发的一个开源项目,它基于Apache的jakarta-cocoon项目,利用了Servlet和Continuation...
Pushlet是基于Comet技术的一种实现,它为Java开发者提供了一种高效的服务器推送解决方案。 一、Comet技术 Comet是一种允许服务器长时间保持HTTP连接的技术,它打破了传统的Web应用模型,即客户端发起请求,服务器...
Pushlet 是一种基于 Java 的实时通信框架,用于实现在服务器端向客户端主动推送消息的功能,而无需客户端不断轮询。这种技术在构建实时应用程序,如聊天室、实时股票更新或在线游戏等场景中非常有用。以下是关于 ...
标题中的“通过推送机制(Tomcat comet,pushlet)实现进度条”涉及到的是Web应用中的一种实时通信技术,主要用于提供动态更新和用户交互。这里主要介绍Tomcat的Comet和Pushlet技术,以及如何利用它们来创建一个...
2. **实时推送**:Pushlet负责后台的数据推送,一旦有新的聊天消息,服务器会立即通过已建立的长连接将消息推送给相关的客户端。 3. **多用户互动**:通过ExtJS的数据管理,可以轻松处理多个用户之间的交互,如添加...
PUSHLET是一种基于Java技术实现的即时通讯系统,它允许服务器主动向客户端推送数据,而无需客户端持续轮询请求。这种技术在实时性要求高的应用中非常常见,如在线聊天、股票交易、游戏等场景。本实例将展示如何在...
"Pushlet聊天工具"是一个基于特定技术实现的通信软件,主要功能是提供实时的信息传递服务。根据提供的标签“源码”和“工具”,我们可以推断这个压缩包可能包含了一个聊天工具的源代码,用于帮助开发者理解和学习...
总的来说,Pushlet是早期实现服务器向客户端实时推送数据的一种解决方案,虽然现在可能已经被其他技术所取代,但它在当时的Web开发中起到了重要的作用,对于理解实时通信机制仍然具有一定的学习价值。
2. **创建Java后台服务**:编写服务端代码,处理业务逻辑,并准备要推送的数据。 3. **创建反向AJAX通道**:在JavaScript中创建反向AJAX通道,注册事件监听器。 4. **客户端订阅**:在客户端JavaScript代码中订阅...