HI-LOW读者社区

HI-LOW读者社区

当前位置: 主页 > 写法交流 >

干货:如何构建一个消息推送平台

时间:2019-01-17 20:52来源:网络整理 作者:佚名 点击:
原标题:干货:如何构建一个消息推送平台01背景B/S架构下很多业务场景下我们需要服务端主动推送消息到客户端,在

原标题:干货:如何构建一个消息推送平台

01

B/S架构下很多业务场景下我们需要服务端主动推送消息到客户端,在html5之前一般使用长轮询

除此之外还有iframe流或者Flash

Socket

的方式来实现,而长轮询的方式缺点很明显,频繁交互的情况下,大量的连接被建立和释放,并且交互频率受限于两次http的请求间隔,html5开始可以使用websocket全双工的通信协议,在tomcat和jetty都有实现。

虽然在java1.4以后可以用nio包实现非阻塞的websocket通信,但是使用起来太过底层和复杂;netty封装了nio,使用了大量异步和事件驱动,封装了拆包粘包,实现了网络编程和业务分离,但即便如此,使用和优化netty还是需要深厚的网络编程知识,况且我们需要的仅仅是用户与用户之间的文本消息的推送,这里我们介绍一个基于netty实现的websocket服务端框架,socket.io屏蔽了使用netty的细节,针对聊天场景做了高度封装,并且提供了包含WEBSOCKET、POLLING等多种推送方式的支持,同时支持namespace

命名空间

、broadcast

广播

、room

房间/聊天室

、event

业务事件

、应用层ack机制。

02

构建一个统一的文本消息推送平台,可以在此之上构建业务系统,比如:客服系统、内部聊天工具、站内信、事件系统等。基础平台要做到用户管理、状态管理、文本消息发送/推送

群/点对点

、图片/文件推送、未读消息管理、历史消息、会话管理。

03

业务架构

restful:通用接口http服务层、提供鉴权、发送消息、历史消息、离线消息、会话等相关接口

logic:业务逻辑层、消息/会话持久化、用户状态、连接状态存储、离线消息

router:路由层、消息路由、把消息推送到用户连接的connector

connector:连接层、提供消息推送服务、维护房间、ack

消息的上行是走的restful,在这层可以做uniauth

内部的统一登录平台

权限验证、负载均衡等,也让connector更轻量级,依赖更少;connector是有状态的,保持着用户的连接信息,同时要记录用户和connector的映射关系,以用于router层在推送消息时路由到对应的节点,connector使用单独的物理机来运行,因为虚拟主机并不能稳定保证较高并发的长连接数量。

04

轻量级的消息发送

一个消息推送平台最重要的是高可用性和最终一致性

消息可达

,所以消息发送可以做的非常轻量,发送消息时会带上客户端生成的唯一消息id,同时客户端持久化,服务端只需要把消息写到mq即发送成功,然后logic消费mq再做异步批量的消息持久化,从可用性角度来说,发送消息并不依赖websocket,而是通过restful服务,更加高可用和可扩展。消息发送的可靠性,没有依赖于rabbitmq的事务或者publisher

confirms,后面介绍专门的机制来保证。

05

点对点/群消息

消息我们定义了三种事件类型,MessageCategoryEnum

MSG:文本消息,包含图片、文件、语音、文字等子类型。

IQ:操作消息,客户端用来做某些特殊动作处理。

STATUS:状态消息,和用户上下线等状态有关。

消息体如下

对于点对点消息来说,发送者和接受者都是一个用户id,对于群消息来说,接受者可能是一个SESSION

会话

,会话需要提前创建,会话中包含若干的用户,使用socket.io的room功能,很方便的实现一个会话,room就是SESSION的id。

1.

用户上下线的时候都要主动加入/离开和自己有关的所有room

com.corundumstudio.socketio.transport.NamespaceClient.joinRoom

String

room

2.

点对点消息推送就调用

com.corundumstudio.socketio.transport.NamespaceClient.sendEvent

String

事件类型,

AckCallback

ack,

Object...

消息

SocketIOMessage

3.

群消息推送就调用

com.corundumstudio.socketio.BroadcastOperations.sendEvent

String

事件类型,

Object

消息

SocketIOMessage

,

BroadcastAckCallback

ack

06

消息可达保证

QoS

使用六报文的方式保证消息可达,图中演示的是三报文的消息发送阶段。

1.client-A向im-server发送一个消息请求包,即msg:R;

2.im-server在成功处理后,回复client-A一个消息响应包,即msg:A;

3.如果此时client-B在线,则im-server主动向client-B推送一个消息通知包

不在线做离线存储

,即msg:N;

4.client-B向im-server发送一个ack请求包表示msg已经收到,即ack:R;

5.im-server在成功处理后,回复client-B一个ack响应包,即ack:A;

6.im-server主动向client-A发送一个ack通知包,即ack:N;

7.client-A发出消息后,超过设定的某个时间没有收到ack:N,那么我们认为消息没有推送成功

用户离线除外,用户离线,服务端会模拟一个ack:N

,需要客户端重发,服务端根据客户端id幂等处理;

(责任编辑:admin)
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
推荐内容