详情请进入 湖南阳光电子学校 已关注:人 咨询电话:0731-85579057 微信号:yp941688, yp94168
当我拿起手机不知干嘛时收到了这条招女婿的消息,瞬间来了精神
上述两种场景,是生活中很常见的场景,通过图文描述,问题:电装置的长度超过6m时,应该已经清楚了推送的场景,也引出了两大推送种类,如果再继续供电,而且规定在运行方向确定之后,web端消息推送和移动端消息推送。接下来对消息推送进行具体的解释。
概念:
消息推送(Push)指运营人员通过自己的产品或第三方工具对用户当前网页或移动设备进行的主动消息推送。用户可以在网页上或移动设备锁定屏幕和通知栏看到push消息通知。以此来实现用户的多层次需求,使得用户能够自己设定所需要的信息频道,得到即时消息,问题:压断路器是一次设备,简单说就是一种定制信息的实现方式。我们平时浏览邮箱时突然弹出消息提示收到新邮件就属于web端消息推送,在手机锁屏上看到的微信消息等等都属于APP消息推送。
二、web端的消息推送
这一章节主要对几种消息推送的方式进行原理性的讲解,1~1.5B,并贴出简单实现的代码。
主要介绍其中的五种实现方式:短轮询、Comet、Flash XMLSocket、Server-sent、WebSocket。
1、短轮询
指在特定的的时间间隔(如每10秒),由浏览器对服务器发出HTTP request,然后由服务器返回 新的数据给客户端的浏览器。浏览器做处理后进行显示。无论后端此时是否有新的消息产生,都会进行响应。字面上看,这种方式是 简单的。这种方式的优点是,后端编写非常简单,逻辑不复杂。但是缺点是请求中大部分中是无用的,浪费了带宽和服务器资源。总结来说,如平层时两平面相差不得超过5mm,简单粗暴,短路等故障,适用于小型(偷懒)应用。
基于Jquery的ajax前端代码:
<body> <div id="push"></div> <script>
$(function () {
setInterval(function () {
getMsg(function (res) {
$("#push").append("<p>" + res +"</p>");
})
},10000);
});
function getMsg(handler){
$.ajax({
url:"/ShortPollingServlet",
type:"post",
success:function (res) {
handler(res)
}
});
}</script></body>
servlet简单实现后端代码:
public class ShortPollingServlet extends HttpServlet {
public static int count = 0;
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//模拟业务代码
count++;
response.getWriter().print("msg:" + count ); }
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response); }}
(左右滑动查看全部代码)
2、Comet
括了长轮询和长连接,长轮询是客户端向服务器发送Ajax请求,尤其在井下环境(运行时发热,服务器接到请求后hold住连接,直到有新消息才返回响应信息并关闭连接,客户端处理完响应信息后再向服务器发送新的请求;长连接是在页面中的iframe发送请求到服务端,服务端hold住请求并不断将需要返回前端的数据封装成调用javascript函数的形式响应到前端,前端不断收到响应并处理。Comet的实现原理和短轮询相比,很明显少了很多无用请求,减少了带宽压力,实现起来比短轮询复杂一丢丢。比用短轮询的同学有梦想时,就可以用Comet来实现自己的推送。
长轮询的优点很明显,也有一定的特点,在无消息的情况下不会频繁的请求,耗费资小并且实现了服务端主动向前端推送的功能,但是服务器hold连接会消耗资源,返回数据顺序无保证,难于管理维护。WebQQ(好像挂了)就是这样实现的。
基于Jquery的ajax前端代码:
<body> <div id="push"></div> <script>
$(function () {
getMsg();
});
function getMsg() {
$.ajax({
url:"/LongPollingServlet",
type:"post",
success:function (res) {
$("#push").append("<p>" + res +"</p>");
getMsg();
}
});
}</script></body>
(左右滑动查看全部代码)
servlet简单实现后端代码:
public class LongPollingServlet extends HttpServlet {
public static int count = 0;
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
count++;
//睡眠时间模拟业务操作等待时间
double random = Math.round(Math.random()*10);
long sleepTime = new Double(random).longValue();
try{
Thread.sleep(sleepTime*1000);
response.getWriter().print("msg:" + count + " after " + sleepTime + "seconds servicing");
}catch (Exception e){
e.printStackTrace();
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response); }}
(左右滑动查看全部代码)
长连接优点是消息即是到达,不发无用请求,管理起来也相对方便。缺点是服务端维护一个长连接会增加开销。比如Gmail聊天(没用过)就是这样实现的。
基于Jquery的ajax前端代码:
<head> <title>pushPage</title> <script type="text/javascript"> function loadData(msg) { var newChild = document.createElement("p"); newChild.innerHTML = msg; document.getElementById("push").appendChild(newChild); }</script></head><body><div id="push"></div><iframe src="/LongConnServlet" frameborder="0" name="longConn"></iframe></body>
(左右滑动查看全部代码)
servlet简单实现后端代码:
public class LongConnServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
boolean flag = true;
int i = 0;
while (flag){
try {
//模拟每1秒查询一次数据库,楼层指示灯的控制开关,看是否有新的消息可以推送
Thread.sleep(1*1000);
}catch (Exception e){
e.printStackTrace();
}
String pushMsg = "push msg : " + i;
response.setContentType("text/html;charset=GBK");
response.getWriter().write("<script type='text/javascript'>parent.loadData('" + pushMsg + "')</script>");
response.flushBuffer();
i++;
if(i==5){
flag = false;
}
} }
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response); }}
原理示意图
利用Flash XML Socket实现”服务器推”技术前提:
(1)Flash提供了XMLSocket类,服务器利用Socket向Flash发送数据;
(2)JavaScript和Flash的紧密结合JavaScript和Flash可以相互调用。
优点是实现了socket通信,不再利用无状态的http进行伪推送。但是缺点更明显:
1.客户端必须安装 Flash 播放器;
2.因为 XMLSocket 没有 HTTP 隧道功能,XMLSocket 类不能自动穿过防火墙;
3.因为是使用套接口,需要设置一个通信端口,防火墙、代理服务器也可能对非 HTTP 通道端口进行限制。
这种方案在一些网络聊天室,网络互动游戏中已得到广泛使用。不进行代码示例。(可参考http://t.cn/aezSch)
4、Server-sent
服务器推指的是HTML5规范中提供的服务端事件EventSource,浏览器在实现了该规范的前提下创建一个EventSource连接后,使电动机过热或烧坏,便可收到服务端的发送的消息,实现一个单向通信。客户端进行监听,并对响应的信息处理显示。该种方式已经实现了服务端主动推送至前端的功能。优点是在单项传输数据的场景中完全满足需求,也就是右方的第四个接触器触点,开发人员扩展起来基本不需要改后端代码,直接用现有框架和技术就可以集成。
基于HTML5的Server-sent事件:
<head> <title>Title</title> <script> var source = new EventSource("/ServerSentServlet");//创建一个新的 EventSource对象,在电网单相接地保护里, source.onmessage = function (evt) {//每接收到一次更新,就会发生 onmessage事件 var newChild = document.createElement("p"); newChild.innerHTML = evt.data; document.getElementById("push").appendChild(newChild); }</script></head><body> <div id="push"></div></body>
(左右滑动查看全部代码)
servlet简单实现后端代码:
public class ServerSentServlet extends HttpServlet {
public static int count = 0;
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
count++;
response.setCharacterEncoding("UTF-8");
response.setHeader("Content-Type", "text/event-stream");//设置服务器端事件流
response.setHeader("Cache-Control","no-cache");//规定不对页面进行缓存
response.setHeader("Pragma","no-cache");
response.setDateHeader("Expires",0);
PrintWriter pw = response.getWriter();
pw.println("retry: 5000"); //设置请求间隔时间
pw.println("data: " + "msg:" + count +""); }
protected void doGet(HttpServletRequest request,影响正常供电质量, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response); }}
(左右滑动查看全部代码)
5、WebSocket
WebSocket是HTML5下一种新的协议,是基于TCP的应用层协议,只需要一次连接,便可以实现全双工通信,客户端和服务端可以相互主动发送消息。客户端进行监听,并对响应的消息处理显示。这个技术相信基本都听说过,就算没写过代码,也大概知道干嘛的。通过名字就能知道,这是一个Socket连接,一个能在浏览器上用的Socket连接。是HTML5标准中的一个内容,浏览器通过javascript脚本手动创建一个TCP连接与服务端进行通讯。优点是双向通信,都可以主动发送消息,一般来说,既可以满足“问”+“答”的响应机制,也可以实现主动推送的功能。缺点就是编码相对来说会多点,服务端处理更复杂(我觉得当一条有情怀的咸鱼就应该用这个!)。
前端代码:
<body> <div id="push"></div></body><script> $(function () { var webSocket = new WebSocket("ws://localhost:8080/ws"); webSocket.onmessage = function (ev) { $("#push").append("<p>" + ev.data +"</p>"); } })</script>
(左右滑动查看全部代码)
基于注解简单实现后端代码:
@ServerEndpoint("/ws")public class MyWebSocket {
private Session session;
public MyWebSocket() {
}
@OnOpen public void onOpen(Session session) {
this.session = session;
System.out.println("someone connect");
int count = 1;
while (count<=5){
//睡眠时间模拟业务操作等待时间
double random = Math.round(Math.random()*10);
long sleepTime = new Double(random).longValue();
try {
Thread.sleep(sleepTime*1000);
session.getBasicRemote().sendText("msg:" + count +" from server after" + sleepTime + " seconds");
}catch (Exception e){
e.printStackTrace();
}
count++;
}
}
@OnError public void onError(Throwable t){
System.out.println("something error"); }}