SAE最近新推出了CHANEL服务,就是由服务器端发起的主动推送服务。通过这个服务就可以简单的实现在线聊天,在线客服等。
这里对具体能开发的应用就不赘述了。主要来说一下如何实现。
首先需要下载SAE服务支持的JAR包。下载地址<a href="http://sae4java.sinaapp.com/lib/sae-local-1.1.0.jar" title="sae-local-1.1.0.jar 下载" target="_blank"></a>并在工程中添加此JAR包在LIB中。
下面就是我的程序部分,
1、 INDEXSEVLET,这个大家自定,也可以直接把这部分程序写在INDEX.JSP中。这里就是为用户创建一个CHANEL对象,并产生一个CHANEL服务的URL。
Java代码
import java.io.IOException;
import java.io.PrintWriter;
import java.util.UUID;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.sina.sae.channel.SaeChannel;
public class IndexServlet extends HttpServlet {
/**
* The doGet method of the servlet. <br />
*
* This method is called when a form has its tag value method equals to get.
*
* @param request the request send by the client to the server
* @param response the response send by the server to the client
* @throws ServletException if an error occurred
* @throws IOException if an error occurred
*/
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request,response);
}
/**
* The doPost method of the servlet. <br />
*
* This method is called when a form has its tag value method equals to post.
*
* @param request the request send by the client to the server
* @param response the response send by the server to the client
* @throws ServletException if an error occurred
* @throws IOException if an error occurred
*/
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//String user = UUID.randomUUID().toString().replace("-", "");
//request.getSession().setAttribute("user", user);
SaeChannel channel = new SaeChannel();
String user="bingobing";
String name = user;//channel名称(如果是一对一的推送服务,那么每个用户的CHANNEL名称应该是不同的,当推送消息时就是依据这个名字)
int duration = 1000;//channel过期时间(单位为秒)
String url = channel.createChannel(name, duration);//返回值为WebSocket的url
response.sendRedirect("index.jsp?url="+url);
}
}
2、在INDEX.JSP页面中根据之前产生的CHANEL服务URL将JS客户端连接上CHANEL服务
Java代码
< %@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
< !DOCTYPE HTML>
<html>
<head>
<script type="text/javascript" src="http://channel.sinaapp.com/api.js"></script>
<script type="text/javascript">
var socket = new sae.Channel('< %=request.getParameter("url") %>');//此处url为上面创建channel返回的url
socket.onopen = function(){
alert("open socket!");
}
//设置channel打开事件,
socket.onmessage = function(message){//设置接收CHANNEL服务推送消息事件
//其中message对象的data字段为channel发送的消息,如上范例为"this message"
alert(message.data);
}
</script>
</head>
<body>
</body>
</html>
3、通过服务端向指定的CHANNEL客户端推送消息
Java代码
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.sina.sae.channel.SaeChannel;
public class ChanelService extends HttpServlet {
/**
* The doGet method of the servlet. <br />
*
* This method is called when a form has its tag value method equals to get.
*
* @param request the request send by the client to the server
* @param response the response send by the server to the client
* @throws ServletException if an error occurred
* @throws IOException if an error occurred
*/
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request,response);
}
/**
* The doPost method of the servlet. <br />
*
* This method is called when a form has its tag value method equals to post.
*
* @param request the request send by the client to the server
* @param response the response send by the server to the client
* @throws ServletException if an error occurred
* @throws IOException if an error occurred
*/
SaeChannel channel = new SaeChannel();
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//String name=(String) request.getSession().getAttribute("user");
String name="bingobing";
int nums=channel.sendMessage(name, "aaaaa");//通过指定的CHANNEL服务名称,向使用该CHANNEL服务的客户端推送消息
response.getWriter().print(nums);
}
}
当通过网页访问ChanelService 时,所有使用BINGOBING名称的CHANNEL客户端都会收到一条内容为AAAAA的消息。客户端并没有进行任何操作,完全由服务器主动推送至客户端。
做了个简单的DEMO而已,具体的应用还没有想好,不过实现方式真的很简单,这里就想到了之前为一个朋友做的微信公众平台的一个在线客服功能模块,客户要求,当微信公众平台关注用户向微信公众号发送指定规则拼接的客服请求时,客服人员能通过自行开发管理平台的后台客服处理界面,能实时接收到用户的客服请求内容,并即时向客户进行返回,当时的实现方式是通过AJAX轮询的方式,来实现实时性要求,不过现在有了CHANNEL服务,就很容易实现了。
当客服人员登录管理平台的客服处理界面后,创建一个指定名称的CHANNEL服务,并链接上此CHANNEL服务。当微信公众号关注分析提出在线客服请求后,将客服请求内容通过调用CHANNEL服务,向指定名称的服务发送消息,这样客服就能实时获取到粉丝的请求,并进行反馈,这样的好处在于1、避免了AJAX轮询导致的反复请求服务器,减少了服务器资源的开销;2、AJAX轮询的请求频率有一定的延迟,无法做到实时,只能做到一个很高频率的循环而已,用了CHANNEL服务,能实现实时性要求。