一种传输消息的方法和系统与流程

文档序号:15358383发布日期:2018-09-05 00:18阅读:266来源:国知局

本申请涉及一种传输消息的方法和系统,属于计算机技术领域。



背景技术:

发布/订阅消息系统如今已经广泛应用于多种情况下的传输消息中,在一个发布/订阅消息系统中,发布者和订阅者都不是直接和对方联系,而是通过一个中间代理来转发消息。在这种情况下,发布者无需知道任何关于订阅者的信息,而订阅者只需要关注它感兴趣的主题就可以了,无需知道是哪个具体的客户端在给它发布消息。通过中间代理来转发消息,实现了发布者和订阅者的解耦。

不过这种系统也存在一些缺陷,在这种传统的发布/订阅消息系统中,中间代理(比如服务器)通常只能单节点运行,而不能支持集群模式,这意味着在这样的系统中,客户端(也就是发布者和订阅者)的连接数量是有限的,消息并发的数量也不能太高,无法动态扩容,在这方面需要改进。



技术实现要素:

本申请提供一种传输消息的方法和系统,用以解决目前传统的发布/订阅消息系统的服务器不能集群,难以支持高并发量消息的问题。所述方法包括如下步骤:

接收用户端发送的消息;

根据消息的内容建立键值对;

根据所述键值对中的键,进行消息路由。

对应的,本申请还提供一种传输消息系统,所述系统包括:一种传输消息系统,其特征在于,包括:

服务器,接收来自用户端的消息,并根据消息的内容建立键值对,根据所述键值对中的键,通过消息代理客户端调用消息代理装置。

和消息代理装置,接收来自消息代理客户端的调用指令,进行消息路由。

通过采用本发明的方案,实现多个服务器利用消息代理装置对消息进行订阅/发布,也就是实现了服务器的集群模式,提高了发布/订阅服务器的并发处理能力,在集群模式下可以动态扩容,扩展性更好。

附图说明

此处所说明的附图用来提供对本申请的进一步理解,构成本申请的一部分,本申请的示意性实施例及其说明用于解释本申请,并不构成对本申请的不当限定。在附图中:

图1为本申请一个方法实施例的流程示意图;

图2是本申请一个实施例中的主题——用户端连接键值对结构示意图;

图3为mqtt服务器解析connect控制包的流程示意图;

图4为mqtt服务器解析publish控制包的流程示意图;

图5为本申请中mqtt服务器调用redis订阅客户端的流程示意图;

图6为本发明一个系统实施例的系统结构示意图;

图7为本发明另一个系统实施例的系统结构示意图。

具体实施方式

为使本申请的目的、技术方案和优点更加清楚,下面将结合本申请具体实施例及相应的附图对本申请技术方案进行清楚、完整地描述。显然,所描述的实施例仅是本申请一部分实施例,而不是全部的实施例。基于本申请中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都属于本申请保护的范围。

一种传输消息的方法,如图1所示,图1为本申请实施例所提供的流程示意图,包括如下步骤:

s1,接收用户通过用户端发送的消息。在一个订阅/发布系统中,用户端既可以是消息订阅者,也可以是消息发布者。同时,一个用户也可以采用多种途径或者设备来连接服务器,比如同一个用户他可以采用手机、电脑或者ipad等多种方式来连接服务器。在通常的情况下,用户端都是连接到一个服务器进行彼此间的订阅/发布的,这虽然也可以实现用户之间的传输消息,但是在这种情况下,服务器只能支持单节点运行,而不能支持服务器的集群模式。

s2,根据消息的内容建立键值对。在用户端发到服务器的消息中,通常包含有很多内容,比如用户名、密码、用户端与服务器之间的连接标识、用户需要订阅/发布的主题,在一个发布者发送的消息中,还会包括用户需要发布的内容等等。

通常这些消息都是采用具有固定格式的数据包发送而来的,这里,服务器可以通过api接口进行解析,进而提取出发来的消息中所包含的内容。

根据用户的不同需求,发来的数据包格式也会不一样,从而提取出的消息内容也会不同。这其中的一些内容并不是其他用户所需要的,比如订阅者并不需要发布者的用户命和密码等。订阅者需要的内容是消息里所包含的用户需要订阅的主题和发布者所发布的内容。此外,服务器还需要知道是哪个用户端连接到服务器,以及怎么把消息准确的按照路线转发过去,也就是在这里,说需要一个标识来唯一对应的代表一条用户端与服务器之间的连接,以便服务器能够根据该标识识别用户端,准确的将消息发送到相关的订阅者。用户端与服务器之间的连接标识在各种情况下有各种表现形式,比如用户端标识、用户标识等等,根据不同情况而定。同一个用户有可能具有多种连接到服务器的途径,这时候它就会具有多个不同的连接标识,每个连接标识唯一的代表了一条用户到服务器的连接。多个标识可以数组的形式组合在一起形成一个用户端连接标识队列。

获取了消息的内容以后,就可以根据用户端与服务器之间的连接标识和用户需要订阅的主题建立键值对,即建立主题——用户端连接键值对,这里键值对的表现形式可以有多种,比如字典(dictionary)、映射(map)或者关联数组(associativearray)等。在一个主题——用户端连接键值对中,用户端订阅的主题为键,用户端到服务器的连接标识队列为值。

这样在知道了主题之后,通过查找键值对,就可以知道所有订阅了该主题的连接标识,进而可以根据该连接准确的把发布者发布的消息发送到订阅者中。

此外,还可以建立用户-连接键值对,键为用户名,值为数组,数组中的每个元素是连接标识,这里是由于是同一个用户可能有多个终端(手机,pad),可能同时连接多次服务器.也存在这样的情况,一个用户通过某终端多次连接服务器(可能是恶意的),这样通过用户-连接键值对,服务器就知道每个用户连接了多少终端了,可以揪出那些恶意发送消息的用户。

s3,根据所述键值对中的键,进行消息路由。在建立了主题——连接键值对后,当一个用户在订阅时,服务器根据主题——连接键值对中的键值(也就是用户订阅的主题)作为消息代理客户端的频道参数,调用消息代理装置执行订阅操作,订阅消息代理中和主题名称相同的频道。

而用户在发布消息时,则以发布者的主题作为消息代理客户端的频道参数,以用户需要发布的内容作为消息代理客户端的消息参数,调用消息代理装置执行发布操作,进行消息发布,将消息发布至每一个订阅了该主题的消息代理客户端。为了提升性能,消息代理还可以采用集群的模式,集群间的每个节点之间都能互相广播,这样任意一个消息发布过来,每个消息代理都可以收到这个发布消息,利用消息代理集群,也提升了服务器集群处理并发的性能。

由此可见,在用户通过前述的方法在服务器上订阅了主题后,本质也就是用户通过服务器订阅了消息代理中的和主题对应的频道。这里首先说明一点,由于有些消息代理不能同时进行发布和订阅操作,方便起见,在服务器上设置消息代理订阅客户端和消息代理发布客户端。这里的发布客户端和订阅客户端可以在同一个服务器,也可以在不同的服务器上。

由前述的内容可以知道发布者发布一个主题和相关的内容后,服务器解析,并得到该主题和他想要发布内容,然后,调用发布客户端以主题作为频道参数,以用户需要发布的内容作为消息参数,调用消息代理执行发布操作,发布消息至订阅了该频道的消息代理订阅客户端。

消息代理订阅客户端收到消息后,再以此时的频道参数作为主题来查询服务器中的主题——连接键值对,这样就得到了该主题所对应的连接标识队列,换句话说,就是得到了所有订阅该主题的用户连接途径,然后只需要遍历这些用户连接途径,向每一个用户端发送包含发布者所发布的内容的消息,准确的把发布的内容传输到订阅者。在本发明的方案中,由于这些消息代理客户端并不要求布置在同一个服务器上,由此在多个独立的服务器之间利用消息代理的发布/订阅功能实现了服务器的集群,提高了发布/订阅服务器的并发处理能力,在集群模式下可以动态扩容,扩展性更好。

为了更进一步具体的说明本发明的实现过程,以利用redis数据库的发布/订阅功能实现mqtt服务器的集群做更具体的说明。

redis虽然是一种常用的数据库,但是它也具有发布/订阅功能,在本发明中做为一个消息代理(messagebroker)。mqtt,即messagequeuingtelemetrytransport,又称为消息队列传输协议,是一种基于代理的发布/订阅的消息传输协议。mqtt服务器在当前已经有了一些开源实现,比如mosca等,但是这些mqtt服务器都不支持集群模式,只能单节点运行。下面将说明如何利用redis数据库的发布/订阅功能来实现mqtt服务器的集群。

在用户端和mqtt服务器之间通过控制包传输消息,该控制包遵从mqtt的协议格式,服务器通过mqtt协议接口解析和封装控制包。通常来说,控制包中包括publish(发布),subscribe(订阅),unsubscrible(取消订阅),connect(连接),disconnect(断开连接),pingreq(心跳)等,服务器通过接口解析,可以获取控制包中所包含的内容,对于不同的mqtt控制包,进行不同的处理过程。

首先用户端需要连接到服务器,此时用户端发送一个connect控制包到服务器,一个连接控制包在其内容中包含有clientid(用户端标识)、主题、主题对应的内容、用户名和密码等。图3为mqtt服务器解析connect控制包的流程示意图。clientid在每个连接控制包中是必须有的,服务器使用用户端标识符(clientid)识别用户端,连接服务器的每用客户端都有唯一的用户端标识。服务器通过端口解析该控制包后获得该用户端标识,根据connect控制包中的用户名和密码,进行用户端认证。如果认证失败,则向用户端发送connack控制包(connack是作为服务器对用户端发出的connect控制包的响应),拒绝用户端连接,否则就在缓存里更新用户-连接队列键值对。具体的说,如果缓存中存在该用户,则向该用户对应的客户端连接队列中添加本次连接的信息(即本次连接的用户端id)。否则,在用户-连接缓存中添加该用户,新建该用户对应的客户端连接队列,并向该队列中添加本次连接的信息。然后向客户端发送connack控制包,接受客户端连接。

连接成功以后,当一个用户希望向mqtt订阅一个主题时,它就会发送一个subscribe控制包给服务器,此时如果用户端订阅的主题是第一次被订阅,则服务器在缓存中新建该主题对应的用户端标识队列,并向该队列中添加本次连接的信息(即本次连接的用户端标识)。否则,直接向该主题对应的客户端连接标识队列中添加本次连接的用户端标识。然后,检查该客户端订阅的主题是不是第一次被订阅,如果是第一次则以该主题作为频道参数,调用redissubscribe客户端向redis订阅该频道,并返回suback控制包,如果不是第一次就直接返回suback控制包。subback控制包由服务器发送给用户端,表示已经收到用户端的订阅控制包并且正在处理。

主题——连接键值对和用户——连接键值对一般就存储在服务器的缓存中,其数据结构可以使用字典(dictionary)、映射(map)或者关联数组(associativearray)等。在一个主题——连接键值对中,用户端订阅的主题为键,用户端到服务器的连接标识队列为值,连接标识队列采用数组实现,在本实施例中,数组中的每个元素即为不同的用户端标识。例如分别有用户1订阅了主题1和主题2,用户2订阅了主题1和主题3,用户3订阅了主图2和主题3,用户4订阅了主题2,用户5订阅了主题3,那么最后形成的主题——连接键值对其数据结构如图2所示。

在一个用户作为发布者的时候,它向服务器发布一个publish控制包,publish控制包中包含主题和有效载荷(即用户需要发布的内容),mqtt服务器提取控制包中的主题和有效载荷,以主题作为redis客户发布端的频道参数,以有效载荷作为redis客户端的消息参数,调用redis客户发布端进行消息发布,其过程如图4所示。

redis订阅客户端在收到发布端发来的消息以后,则以接受到的频道参数作为主题查询缓存中的主题——连接键值对,得到该主题所对应的用户端标识队列,然后遍历用户端标识队列中所包含的每一个用户端标识,通过这些用户端标识向它们所对应的每一个用户发送一个publish控制包,该控制包中的有效载荷即为redis订阅客户端所收到的消息参数,如图5所示。通过前述的方法,即完成了整个消息路由过程。

同样的,用户端还能基于类似的原理执行断开连接和取消订阅的操作。在收到用户端发来的取消订阅的控制包(unsubscribe控制包)后,服务器从主题对应的用户端连接标识队列中删除用户端id信息;如果主题对应的客户端连接队列为空,则从主题-连接缓存中删除该主题以及该主题对应的客户端连接队列,然后调用redissubscribe客户端向redisunsubscribe该主题,然后向客户端返回unsuback控制包。表示确认服务器收到unsubscribe控制包。

断开连接的操作也是类似,首先解析disconnect控制包,遍历用户所订阅的主题,从客户端订阅的所有主题对应的客户端队列中删除连接信息。针对每个主题,如果主题对应的用户端连接标识队列为空,则从主题-连接缓存中删除该主题以及该主题对应的连接标识队列,然后调用redissubscribe客户端向redisunsubscribe该主题;然后从该用户对应的客户端连接标识队列中删除该连接信息。如果该用户对应的客户端队列为空,则从用户-连接缓存中删除该用户以及该用户对应的客户端队列;最后断开客户端连接。通过前述的方法,利用redis数据库的发布/订阅功能实现mqtt服务器的集群。

基于同样的思路,本发明还提供一种传输消息系统,如图6所示,包括:服务器301,接收来自用户端的消息,并根据消息的内容建立键值对,根据所述键值对中的键,通过消息代理客户端3011调用消息代理装置302。

和消息代理装置302,接收来自消息代理客户端3011的调用指令,进行消息路由。

优选的,所述服务器还包括提取模块,所述服务器包括提取模块,用于提取消息的内容中所包括的连接标识、用户需要订阅或发布的主题和用户需要发布的内容。

进一步的,所述服务器还包括键值对化模块,用于建立主题——连接键值对,所述键值对中以用户需要订阅的主题作为键,以连接标识组成的连接标识队列作为值。

更进一步的,所述消息代理客户端包括:消息代理发布客户端和消息代理订阅客户端,所述发布模块以用户需要发布的主题作为消息代理发布客户端的频道参数,以用户需要发布的内容作为消息代理发布客户端的消息参数,调用消息代理装置进行发布;所述消息代理订阅客户端以用户需要订阅的主题作为消息代理客户端的频道参数,调用消息代理装置进行订阅。

前述的消息代理装置包括具有多个消息代理装置节点的消息代理装置集群。集群中的每个节点都可以互相广播消息,比如在一个mqtt订阅/发布服务器上,可以采用redis数据库集群,来实现mqtt服务器的集群,如图7所示。至于这些模块互相之间是如何进行消息路由的,详细的方法已经在之前的方法说明里进行了具体的描述,这里就不再一一赘述。

当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1