pushlet
pushlet推送是一种将java后台数据推送到web页面的框架技术。下面我会对Pushlet的定时周期性自动推送、需求推送和点对点推送进行讲解(注意:以下提到的监听路径即事件订阅名)。
首先,需要导入从Pushlet官方下载js文件和jar包,如下图结构。
图中选中文件为Pushlet相关文件,jquery提供ajax-pushlet-client.js支持。接下来配置web.xml。
-
<?xml version="1.0" encoding="UTF-8"?>
-
<web-APP xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="webapp_ID" version="3.0">
-
<welcome-file-list>
-
<welcome-file>page/index.jsp</welcome-file>
-
</welcome-file-list>
-
<servlet>
-
<servlet-name>pushlet</servlet-name>
-
<servlet-class>nl.justobjects.pushlet.servlet.Pushlet</servlet-class>
-
<load-on-startup>1</load-on-startup>
-
</servlet>
-
<servlet-mapping>
-
<servlet-name>pushlet</servlet-name>
-
<url-pattern>/pushlet.srv</url-pattern>
-
</servlet-mapping>
-
</web-app>
由于Pushlet的jajax-pushlet-client.js中获取的项目路径时,是默认当作用户放置ajax-pushlet-client.js在web根目录下的,若放置到其它子目录位置时,在获取web项目路径的时项目路径会加上子目录路径,这样去访问pushlet的java服务时就会找不到。所以,这里我们会改写ajax-pushlet-client.js中的获取web项目路径的方法。
原始获取web项目路径的方法如下:
-
_getWebRoot: function() {
-
/** Return directory of this relative to document URL. */
-
if (PL.webRoot != null) {
-
return PL.webRoot;
-
}
-
//derive the basedir value by looking for the script tag that loaded this file
-
var head = document.getElementsByTagName('head')[0];
-
var nodes = head.childNodes;
-
for (var i = 0; i < nodes.length; ++i) {
-
var src = nodes.item(i).src;
-
if (src) {
-
var index = src.indexof("ajax-pushlet-client.js");
-
if (index >= 0) {
-
index = src.indexOf("lib");
-
PL.webRoot = src.substring(0, index);
-
break;
-
}
-
}
-
}
-
return PL.webRoot;
-
},
改写后获取web项目路径的的方法如下:
-
_getWebRoot: function() {
-
/** Return directory of this relative to document URL. */
-
if (PL.webRoot != null) {
-
return PL.webRoot;
-
}
-
//derive the baseDir value by looking for the script tag that loaded this file
-
//获取当前网址,如: http://localhost:8080/PushletNote/index.jsp
-
var webPath = window.document.location.href;
-
//获取主机地址之后的目录,如: /PushletNote/index.jsp
-
var pathName = window.document.location.pathname;
-
//获取主机地址,如: http://localhost:8080
-
var hostPaht = webPath.substring(0,webPath.indexOf(pathName));
-
//获取带"/"的项目名,如:/Pushlet
-
var projectName = pathName.substring(0,pathName.substr(1).indexOf('/')+1);
-
PL.webRoot = hostPaht + projectName + "/";
-
return PL.webRoot;
-
},
这样,就可以不必一定要将ajax-pushlet-client.js不放在web根目录下了。
以下三种推送方式的实现都在以上配置的基础上进行。
index.jsp的代码作用是为了方便统一管理三种方式,代码如下:
-
<%@ 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>Pushlet主页</title>
-
<style type="text/css">
-
*{
-
margin:0px auto;
-
padding:0px;
-
text-decoration: none;
-
list-style:none;
-
font-size:12px;
-
}
-
#main{
-
margin-top:20px;
-
width:500px;
-
height:600px;
-
background:#eee;
-
border-radius:5px;
-
padding-left:30px;
-
padding-top:30px;
-
}
-
.list{
-
}
-
.info{
-
margin-left:10px;
-
}
-
</style>
-
</head>
-
<body>
-
<p id="main">
-
<p class="list">*<a class="info" href="./page/timing_get_pull.jsp">服务向页面定时周期性推送消息Demo</a></p>
-
<p class="list">*<a class="info" href="./page/auto_get_pull.jsp">服务按某种需求向页面推送消息Demo</a></p>
-
<p class="list">*<a class="info" href="./page/one_to_one_get_pull.jsp">一对一推送消息Demo</a></p>
-
</p>
-
</body>
-
</html>
定时周期性推送:
这种方式是在java代码中配置休眠时间,每隔一定时间向web页面推送一次消息,只要web页面js中配置了启动监听,就能获取相应数据。
java代码如下:
-
package com.pushlet;
-
import nl.justobjects.pushlet.core.Event;
-
import nl.justobjects.pushlet.core.EventPullSource;
-
/**
-
* @ProjectName:PushletNote
-
* @ClassName:PushletHelper
-
* @author 御兰草
-
* @email [email protected]
-
* @date 2014年10月10日
-
* @Description:无
-
*/
-
public class PushletHelper {
-
static public class PushletImpl extends EventPullSource{
-
//定义临时数字静态变量
-
private int num = 0;
-
/**
-
* 休眠1秒执行一次pullEvent方法
-
*/
-
@Override
-
protected long getSleepTime() {
-
return 1000;
-
}
-
/* (non-Javadoc)
-
* @see nl.justobjects.pushlet.core.EventPullSource#pullEvent()
-
*/
-
@Override
-
protected Event pullEvent() {
-
Event event = Event.createDataEvent("/pushlet/timing");
-
event.setfield("result", num);
-
num++;
-
return event;
-
}
-
}
-
}
web页面代码如下(这里我的jsp文件名为timing_get_pull.jsp):
-
<%@ 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>服务向页面定时周期性推送消息Demo</title>
-
<script type="text/JavaScript" src='../js/jquery-1.10.2.js'></script>
-
<script type="text/javascript" src='../js/ajax-pushlet-client.js'></script>
-
<script type="text/javascript">
-
function begin(){
-
PL._init();
-
PL.joinListen('/pushlet/timing');
-
}
-
//Pushlet的js中封装方法,产生消息
-
function onData(event) {
-
$("#info").text(event.get("result"));
-
}
-
function stop(){
-
//离开
-
PL.leave();
-
}
-
</script>
-
</head>
-
<body>
-
<p style="margin:0px auto;width:600px;height:400px;background:#eee;border-radius:5px;">
-
<button href="../index.jsp">返回</a>
-
<center id='info'>显示从后台获取的数据</center>
-
<button 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>服务按某种需求向页面推送消息Demo</title>
-
<script type="text/javascript" src='../js/jquery-1.10.2.js'></script>
-
<script type="text/javascript" src='../js/ajax-pushlet-client.js'></script>
-
<script type="text/javascript">
-
//启动监听
-
function begin(){
-
PL._init();
-
PL.joinListen('/pushlet/auto');
-
}
-
var xhr = new XMLHttprequest();
-
//触发服务方法,使其向页面推送消息
-
function trigger(){
-
var count = $("#count").text();
-
var url = PL.webRoot + "PushletServlet?count=" + count;
-
xhr.open("get", url, true);
-
xhr.send(null);
-
}
-
//Pushlet的js中封装方法,产生消息
-
function onData(event) {
-
$("#count").text(event.get("message"));
-
}
-
function stop(){
-
//离开
-
PL.leave();
-
}
-
</script>
-
</head>
-
<body>
-
<p style="margin:0px auto;width:600px;height:400px;background:#eee;border-radius:5px;">
-
<button href="../index.jsp">返回</a>
-
<button style="color:red;">0</span>次消息</center>
-
<button + format(new Date())));
-
Dispatcher.getInstance().unicast(event, "niko");//向ID为niko的用户推送
-
}
-
}
-
/**
-
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletresponse response)
-
*/
-
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
-
doGet(request, response);
-
}
-
}
web客户端代码如下(这里我的jsp文件名为one_to_one_get_pull.jsp):
-
<%@ 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>服务按某种需求向页面推送消息Demo</title>
-
<script type="text/javascript" src='../js/jquery-1.10.2.js'></script>
-
<script type="text/javascript" src='../js/ajax-pushlet-client.js'></script>
-
<script type="text/javascript">
-
//启动监听
-
function begin(){
-
PL.userId ="niko";
-
PL._init();
-
PL.joinListen("/pushlet/onetoone");
-
}
-
var xhr = new XMLHttpRequest();
-
//触发服务方法,使其向页面推送消息
-
function trigger(){
-
var url = PL.webRoot + "OneToOneServlet?";
-
xhr.open("get", url, true);
-
xhr.send(null);
-
}
-
//Pushlet的js中封装方法,产生消息
-
function onData(event) {
-
//用decodeURIcomponent方法解码
-
$("#message").text(decodeURIComponent(event.get("message")));
-
}
-
function stop(){
-
//离开
-
PL.leave();
-
}
-
</script>
-
</head>
-
<body>
-
<p style="margin:0px auto;width:600px;height:400px;background:#eee;border-radius:5px;">
-
<button href="../index.jsp">返回</a>
-
<button style="color:red;"></span></center>
-
<button onclick="stop();">停监听止</button>
-
<fieldset style="margin-top:30px;padding:0px;width:596px;height:auto;">
-
<legend>描述</legend>
-
<p style="text-indent:2em;font-size:12px;">
-
点对点推送消息,这种方式需要重写或改写sessionManager类,然后在pushlet.properties配置文件中的sessionmanager.class属性域改写的SessionManger类路径对应,并在pushlet的js中添加userId属性,并添加传递参数的代码。若不在js中添加userId(次要),不重写Session的createSession方法,则默认所有请求、监听都使用默认创建的Session用户visitor。
-
</p>
-
<p style="text-indent:2em;font-size:12px;">
-
PS:pushlet推送消息不能直接推送中文,需要进行转码再推送。通过方法SessionManager.getInstance().hasSession("niko")获取的boolean值反应该用户是否处于监听状态,若用户已在监听,则返回true,若已调用PL.leave()方法,则SessionManager.getInstance().hasSession("niko")的返回值为false。Event的getField方法的第二个参数为当传递参数中不存在第一个参数字段时默认使用的值。
-
</p>
-
</fieldset>
-
</p>
-
</body>
-
</html>
这样,即实现了消息的点对点推送。这里改写SessionManger并配置不会影响前两种推送方式的执行。 --------------------- 本文来自 第三眼的思绪 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/a123638/article/details/40652555?utm_source=copy
相关阅读
原帖地址:http://blog.csdn.net/meikidd/article/details/7446778最近项目中有服务器端推送的需求,考察了一下,感觉pushlet比较适合