0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

web端的消息推送原理分析

电子设计 来源:电子设计 作者:电子设计 2020-12-25 17:50 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

引言:

在互联网高速发展的时代里,web应用大有取代桌面应用的趋势,不必再去繁琐的安装各种软件,只需一款主流浏览器即可完成大部分常规操作,这些原因都在吸引着软件厂商和消费者。而随着各大厂商浏览器版本的迭代,前端技术的不断革新,消息推送用到的场景也越来越多了。

收发邮件提醒,在线IM聊天,自动化办公提示等等,web系统里总是能见到消息推送的应用。消息推送用好了能增强用户体验,用不好则会起相反的效果。在司空见惯的使用过程中,有没有对其中的原理产生兴趣呢?实现消息推送有N种解决方案,本文针对其中的几种,进行原理性的讲解并附有简单的代码实现。

目录:

一、什么是消息推送

二、web端的消息推送

、实现个性化的推送

一、什么是消息推送

经典场景1

当我在官网观望犹豫时,突然看到了上面消息,一位神秘的徐老板竟然爆出了麻痹戒指!!我的天,于是我果断开始了游戏!这消息很及时!

经典场景2

当我拿起手机不知干嘛时收到了这条招女婿的消息,瞬间来了精神

上述两种场景,是生活中很常见的场景,通过图文描述,应该已经清楚了推送的场景,也引出了两大推送种类,web端消息推送移动端消息推送。接下来对消息推送进行具体的解释。

概念:

消息推送(Push)指运营人员通过自己的产品或第三方工具对用户当前网页或移动设备进行的主动消息推送。用户可以在网页上或移动设备锁定屏幕和通知栏看到push消息通知。以此来实现用户的多层次需求,使得用户能够自己设定所需要的信息频道,得到即时消息,简单说就是一种定制信息的实现方式。我们平时浏览邮箱时突然弹出消息提示收到新邮件就属于web端消息推送,在手机锁屏上看到的微信消息等等都属于APP消息推送。

二、web端的消息推送

这一章节主要对几种消息推送的方式进行原理性的讲解,并贴出简单实现的代码。

主要介绍其中的五种实现方式:短轮询、Comet、Flash XMLSocket、Server-sent、WebSocket。

1、短轮询

指在特定的的时间间隔(如每10秒),由浏览器对服务器发出HTTP request,然后由服务器返回最新的数据给客户端的浏览器。浏览器做处理后进行显示。无论后端此时是否有新的消息产生,都会进行响应。字面上看,这种方式是最简单的。这种方式的优点是,后端编写非常简单,逻辑不复杂。但是缺点是请求中大部分中是无用的,浪费了带宽和服务器资源。总结来说,简单粗暴,适用于小型(偷懒)应用。

基于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); }}

(左右滑动查看全部代码)

3、Flash XMLSocket

在 HTML 页面中内嵌入一个使用了 XMLSocket 类的 Flash 程序。JavaScript 通过调用此 Flash 程序提供的socket接口与服务器端的socket进行通信。JavaScript 在收到服务器端以 XML 格式传送的信息后可以很容易地控制 HTML 页面的内容显示。

原理示意图

利用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"); }}

(左右滑动查看全部代码)

以上是对五种推送方式原理的简单讲解和代码的实现。

三、实现个性化的推送

上面说了很多原理,也给出了简单的代码实现,但是在实际生产过程中,肯定不能用上面的代码,针对自己系统的应用场景选择合适的推送方案才是合理的,因此最后简单说一下实现个性化推送的两种方式。第一种很简单,直接使用第三方实现的推送,无需复杂的开发运维,直接可以使用。第二种就是自己封装,可以选择如今较为火热的WebSocket来实现系统的推送。

1、第三方

在这里推荐一个第三方推送平台,GoEasy。

推荐理由是GoEasy的理念符合我们的选择(可参考http://t.cn/Ex6jg3q):

(1)更简单的方式将消息从服务器端推送至客户端

(2)更简单的方式将消息从各种客户端推送至客户端

GoEasy具体的使用方式这里不再赘述,详见官网。对于后端后端开发者,可直接使用Rest方式调用推送,对于前端或web开发者,可以从web客户端用javascript脚本进行调用推送。

2、封装自己的推送服务

如果是一个老系统进行扩展,那么更推荐使用Server-sent,服务端改动量不会很大。如果是新系统,更推荐websocket,实现的功能功能更全面。

我们以websocket为例,不再贴出具体的代码实现。

我们如果需要使用websocket技术实现自己的推送服务,需要注意哪些点,或者说需要踩哪些坑呢,本文最后列出几点供大家参考:

长连接的心跳处理;

从WebSocket中获取HttpSession进行用户相关操作;

服务端调优实现高并发量client同时在线;

服务端维持多用户的状态;

群发消息;

等等等….

最后贴出上述代码的git库地址,所有demo均可运行。环境为jdk1.8+tomcat8。

http://t.cn/Ex6TRVZ

精选提问:

问1:请问,分布式下的信息推送适合用哪种,信息推送和订阅有什么区别?

答:分布式下我觉得websocket。订阅是索取消息,推送是主动推送消息。

问2:扫码登录是使用websocket实现的吗?

答:实现扫码登陆可以多种方式。轮询可以,websocket也可以,看自己选择。

推荐阅读

RESTful API教程:学习关键的Web服务设计原则

React-native如何变为移动端的弄潮儿

使用消息系统进行微服务间通讯时,如何保证数据一致性

关于作者:徐晓明,普元开发工程师,毕业于辽宁科技大学,专注于使用移动开发平台开发app,负责中国邮政集团移动平台项目邮我行app开发和后台开发运维工作。

审核编辑:符乾江
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Web
    Web
    +关注

    关注

    2

    文章

    1302

    浏览量

    73730
  • 代码
    +关注

    关注

    30

    文章

    4947

    浏览量

    73281
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    电能质量在线监测装置的数据推送频率可以手动调整吗?

    / 新能源并网)设置独立的推送周期。 一、调整方式与配置途径 配置方式 操作方法 适用场景 本地 Web 界面 通过装置自带以太网口访问内置 Web 服务器,在 "通信设置" 或 "数据推送
    的头像 发表于 12-05 15:08 160次阅读
    电能质量在线监测装置的数据<b class='flag-5'>推送</b>频率可以手动调整吗?

    常用Web 实时通信技术:原理+选型,一篇通关

    Web 开发中,实时通信技术的核心目标是实现客户(Browser)与服务器之间低延迟、双向 / 单向的动态数据交互,而非传统 HTTP 的 “请求 - 响应” 模式。以下是 Web
    的头像 发表于 10-27 17:19 527次阅读
    常用<b class='flag-5'>Web</b> 实时通信技术:原理+选型,一篇通关

    蔚来模型化架构如何大幅提升安全上限

    2024年7月,蔚来将行业首个基于模型化架构的「自动紧急制动 AEB」推送上车,蔚来也成为了行业首家使用模型化架构来做主动安全的
    的头像 发表于 08-15 15:35 714次阅读

    【EASY EAI Orin Nano开发板试用体验】使用stream推流代码和WEB服务器代码实现在客户网页上查看摄像头图像

    本帖最后由 donatello1996 于 2025-8-13 20:32 编辑 【EASY EAI Orin Nano开发板试用体验】使用stream推流代码和WEB服务器代码实现在客户
    发表于 08-11 23:15

    从 app_gatt_callback调用这个队列推送函数时,程序出现了硬故障怎么解决?

    ,其大小为 intptr_t。 当我从 \" app_bt_management_c \" allback 调用队列推送 API 时,我的程序可以正常工作。 但是当我从 app_gatt_callback 调用这个队列推送函数时,我的程序出现了硬故障。
    发表于 07-04 06:03

    推进电机盖结构的抗冲击分析及优化

    摘要:高转矩密度、强抗冲击性和低噪声已经成为舰船用推进电机三大特征,以某推进电机的盖结构为分析研究对象,以有限元数值仿真分析为手段,分析了该结构在受到冲击时的反应及随材料属性变化的规
    发表于 06-23 07:12

    WEB组态物联网平台是什么?有什么功能?

    WEB组态物联网平台是一种基于Web技术的物联网(IoT)可视化管理与监控平台,它将 组态软件 的灵活配置能力与 物联网技术 的数据采集、传输、分析功能相结合,通过浏览器即可实现设备监控、数据展示
    的头像 发表于 06-17 15:25 681次阅读

    鸿蒙5开发宝藏案例分享---Web页面内点击响应时延分析

    ! ?️** 二、性能分析工具链** DevTools时间线 - 定位卡顿区域 // 开启性能监测(在Web页面注入) console.time(\'clickRendering\'); // ...业务
    发表于 06-12 17:09

    蔚来世界模型NWM首个版本正式推送

    近日,「蔚来世界模型 NWM」首个版本正式开启推送。首批推送车型为超过40万台的「Banyan 榕」车型。「Cedar 雪松」车型,包括ET9、新ES6、新EC6、新ET5、新ET5T在内,将会于6月底开启推送
    的头像 发表于 06-04 15:13 715次阅读

    基于 HT for Web 的轻量化 3D 数字孪生数据中心解决方案

    ,支持 PC、移动浏览器直接访问,兼容主流操作系统。 轻量化建模体系 : 支持 CAD、BIM 模型导入,通过几何简化、纹理压缩等算法降低模型复杂度,适配 Web 渲染性能。 提供参数化建模工具,可
    的头像 发表于 05-30 14:33 642次阅读
    基于 HT for <b class='flag-5'>Web</b> 的轻量化 3D 数字孪生数据中心解决方案

    小米汽车智驾技术介绍

    后起之秀,小米在宣布造车前被非常多的人质疑,但在“真香”定律下,小米创下了很多友商所不能及的成就。作为科技企业,小米也在智能驾驶领域也不断研发及突破,并推送自动驾驶系统。 小米
    的头像 发表于 03-31 18:17 4818次阅读
    小米汽车<b class='flag-5'>端</b>到<b class='flag-5'>端</b>智驾技术介绍

    「极速探索HarmonyOS NEXT 」阅读体验】+Web组件

    web web应用是基于 Web技术(如HTML、CSS、JavaScript),构建在浏览器中运行的应用,亦称为前端开发。从用户视角来看,手机和平板上的应用多由原生开发打造;而通过浏览器访问的网页
    发表于 03-10 10:39

    WebTCP/UDP测试工具!小白必学~

    WebTCP/UDP测试工具,方便大家进行各种基于TCP和TDP的模拟测试。该测试工具不仅支持TCP和UDP测试,还支持SSL,使用极为便捷。 按照如下测试示例步骤,即可把TCP/UDP web
    的头像 发表于 01-08 18:17 2023次阅读
    <b class='flag-5'>Web</b><b class='flag-5'>端</b>TCP/UDP测试工具!小白必学~

    自动驾驶技术研究与分析

    编者语:「智驾最前沿」微信公众号后台回复:C-0450,获取本文参考报告:《自动驾驶行业研究报告》pdf下载方式。 自动驾驶进入2024年,无疑成为其最火热的一项技术,凭借
    的头像 发表于 12-19 13:07 1546次阅读

    Web缓存的类型及功能分析

    随着互联网的迅速发展,用户对网络内容的访问需求日益增长。为了提高用户体验和降低服务器负担,Web缓存技术应运而生。Web缓存通过存储重复请求的数据,减少了对原始服务器的访问次数,从而加快了数据传输
    的头像 发表于 12-18 09:35 1255次阅读