**前言:**移动互联网蓬勃发展的今天,大部分手机 APP和网站都提供了消息推送功能,如新闻客户端的热点新闻推荐,IM 工具的聊天消息提醒,电商产品促销信息,企业应用的通知和审批流程等等。推送对于提高产品活跃度、提高功能模块使用率、提升用户粘性、提升用户留存率起到了重要作用,作为 APP 和网站运营中一个关键的渠道,对消息推送的合理运用能有效促进目标的实现。
一、浅析web端的消息推送原理
股票曲线实时变化,在线IM聊天等等,Web系统里总是能见到消息推送的应用。消息推送用好了能增强用户体验,实现消息推送有N种解决方案。
1.1、什么是消息推送
消息推送(Push)指运营人员通过自己的产品或第三方工具对用户当前网页或移动设备进行的主动消息推送。用户可以在网页上或移动设备锁定屏幕和通知栏看到push消息通知。以此来实现用户的多层次需求,使得用户能够自己设定所需要的信息频道,得到即时消息,简单说就是一种定制信息的实现方式。我们平时浏览邮箱时突然弹出消息提示收到新邮件就属于web端消息推送,在手机锁屏上看到的微信消息等等都属于APP消息推送。
Web网站推送:
当我们在浏览网站观望犹豫时,突然看到了系统发来一条消息,一位神秘的神豪老板竟然爆出了麻痹戒指!!!我的天,于是我果断开始了游戏!这消息很及时!
APP移动推送:
上述两种经典场景,是生活中比较常见的场景,也引出了两大推送种类,Web端消息推送和移动端消息推送。本篇博客主要介绍Web推送,顺便提一句移动端App常见第三方推送SDK有极光推送、小米推送等等。
****1.2、****Web端实现消息推送的四种方式
主要介绍web端其中的四种实现方式:短轮询、Comet长轮询、Server-sent、WebSocket。
(1)短轮询
指在特定的的时间间隔(如每10秒),由浏览器对服务器发出HTTP request,然后由服务器返回最新的数据给客户端的浏览器。浏览器做处理后进行显示。无论后端此时是否有新的消息产生,都会进行响应。字面上看,这种方式是最简单的。这种方式的优点是,后端编写非常简单,逻辑不复杂。但是缺点是请求中大部分中是无用的,浪费了带宽和服务器资源。总结来说,简单粗暴,适用于小型(偷懒)应用。
(2)Comet长轮询
长轮询是客户端向服务器发送Ajax请求,服务器接到请求后hold住连接,直到有新消息才返回响应信息并关闭连接,客户端处理完响应信息后再向服务器发送新的请求;长连接是在页面中的iframe发送请求到服务端,服务端hold住请求并不断将需要返回前端的数据封装成调用javascript函数的形式响应到前端,前端不断收到响应并处理。Comet的实现原理和短轮询相比,很明显少了很多无用请求,减少了带宽压力,实现起来比短轮询复杂一丢丢。想比用短轮询的同学有梦想时,就可以用Comet来实现自己的推送。
长轮询的优点很明显,在无消息的情况下不会频繁的请求,耗费资小并且实现了服务端主动向前端推送的功能,但是服务器hold连接会消耗资源,返回数据顺序无保证,难于管理维护。WebQQ(好像挂了)就是这样实现的。
(3)Server-sent
服务器推指的是HTML5规范中提供的服务端事件EventSource,浏览器在实现了该规范的前提下创建一个EventSource连接后,便可收到服务端的发送的消息,实现一个单向通信。客户端进行监听,并对响应的信息处理显示。该种方式已经实现了服务端主动推送至前端的功能。优点是在单项传输数据的场景中完全满足需求,开发人员扩展起来基本不需要改后端代码,直接用现有框架和技术就可以集成。
(4)WebSocket
WebSocket是HTML5下一种新的协议,是基于TCP的应用层协议,只需要一次连接,便可以实现全双工通信,客户端和服务端可以相互主动发送消息。客户端进行监听,并对响应的消息处理显示。
这个技术相信基本都听说过,就算没写过代码,也大概知道干嘛的。通过名字就能知道,这是一个Socket连接,一个能在浏览器上用的Socket连接。WebSocket是HTML5标准中的一个内容,浏览器通过javascript脚本手动创建一个TCP连接与服务端进行通讯。优点是双向通信,都可以主动发送消息,既可以满足“问”+“答”的响应机制,也可以实现主动推送的功能。缺点就是编码相对来说会多点,服务端处理更复杂(我觉得当一条有情怀的咸鱼就应该用这个!)。
1.3、实现个性化的推送
上面说了很多实现方案,针对自己系统的应用场景选择合适的推送方案才是合理的,因此最后简单说一下实现个性化推送的两种方式。第一种很简单,直接使用第三方实现的推送,无需复杂的开发运维,直接可以使用。第二种就是自己封装,可以选择如今较为火热的WebSocket来实现系统的消息推送。
①直接用第三方的消息推送服务(并发量多了会收费)
在这里推荐一个第三方推送平台,GoEasy。
推荐理由是GoEasy的理念符合我们的选择(可参考http://t.cn/Ex6jg3q):
(1)更简单的方式将消息从服务器端推送至客户端
(2)更简单的方式将消息从各种客户端推送至客户端
GoEasy具体的使用方式这里不再赘述,详见官网。对于后端后端开发者,可直接使用Rest方式调用推送,对于前端或web开发者,可以从web客户端用javascript脚本进行调用推送。
②封装自己的推送服务
如果是一个老系统进行扩展,那么更推荐使用Server-sent,服务端改动量不会很大。如果是新系统,更推荐websocket,实现的功能功能更全面。
我们如果需要使用websocket技术实现自己的推送服务,需要注意哪些点,或者说需要踩哪些坑呢,本文列出几点供大家参考:
长连接的心跳激活处理;
服务端调优实现高并发量client同时在线(单机服务器可以实现百万并发长连接);
群发消息;
服务端维持多用户的状态;
从WebSocket中获取HttpSession进行用户相关操作;
等等等….
二、WebSocket简介
2.1、websocket的由来
我们经常用的是HTTP协议,而HTTP协议是一种无状态的协议,要实现有状态的会话必须借助一些外部机制如session/cookie或者Token,这或多或少会带来一些不便,尤其是服务端和客户端需要实时交换数据的时候(监控,聊天),这个问题更加明显。为了适应这种环境,websocket就产生了,目的是即时通讯,替代轮询。
2.2、websocket概述
WebSocket 是HTML5一种新的协议。它实现了浏览器与服务器全双工通信(full-duplex)。一开始的握手需要借助HTTP请求完成。WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议。WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。
websocket的特点或作用
-
允许服务端主动向客户端推送数据
-
在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
websocket使用的优点
-
更强的实时性
-
保持连接状态,创建一次连接后,之后通信时可以省略部分状态信息。较少的控制开销,在连接创建后,服务器和客户端之间交换数据时,用于协议控制的数据包头部相对较小。在不包含扩展的情况下,对于服务器到客户端的内容,此头部大小只有2至10字节(和数据包长度有关);对于客户端到服务器的内容,此头部还需要加上额外的4字节的掩码。相对于HTTP请求每次都要携带完整的头部,此项开销显著减少了
websocket使用的缺点
由于websocket使用的持久连接,与服务器一直保持连接,对服务器压力很大
2.3、websocket请求头和响应头
浏览器发送websocket请求头类似如下:
下面是对请求头部解释(比http协议多了Upgrade和Connection,是告诉服务器包协议设计ws):
-
Accept-Encoding:浏览器可以接受的数据的压缩类型。
-
Accept-Language:浏览器可以接受的语言类型。
-
Cache-Control:no-cache不使用强缓存。
-
Connection:Upgrade 通知服务器通信协议提升。
-
Host:主机名。
-
Origin:用于验证浏览器域名是否在服务器许可范围内。
-
Pragma:no-cache HTTP/1.0定义的不使用本地缓存。
-
Sec-WebSocket-Extensions:permessage-deflate; client_max_window_bits
-
Sec-WebSocket-Key:lb69kw8CsB4CrSk9tKa3 g==
握手协议密钥,base64编码的16字节的随机字符串。 -
Sec-WebSocket-Version:13 版本号。
-
Upgrade:websocket 使用websocket协议进行传输数据,而不使用HTTP/1.1。
-
User-Agent:用户代理字符串。
服务器接收到客户端请求后做出响应并返回如下: