利用消息队列MQTT,打造一款属于自己的IM社交软件

MQTT 是一种基于发布订阅模型的即时通讯协议,由于轻巧,开源,易用,耗能少,支持 QOS/遗言(WILL)等特性,正被广泛应用于物联网和移动互联网。

消息队列 MQ 提供了对 MQTT 协议的支持,完全兼容 MQTT 标准协议,但是在使用 MQ MQTT 时,对比标准协议,需要注意两点:
1. 父级 Topic 需要提前创建
根据标准 MQTT 协议,Topic 存在多级,且拥有动态的特性(不需要用户提前定义和创建),但是使用过消息队列 MQ 的用户都知道,MQ Topic是需要通过 MQ 控制台提前创建的,这是因为 MQ MQTT是队列(消息持久化),且 MQ 不仅支持 MQTT 协议,还支持 TCP, HTTP 协议的接入,为了能将不同方式接入的消息互通,比如:用 MQTT 方式发送的消息,用 TCP 方式可以收到;用 HTTP 方式发送的消息,用 MQTT 方式也能收到,故 MQ MQTT 做了以下变通:

定义第一级 Topic 为父 Topic,使用前,需要在 MQ 控制台创建父 Topic,子级 Topic 无需创建,直接在代码中使用。

2. MQ MQTT 支持 p2p,且不需要显示订阅
这一点弥补了标准 MQTT 协议不支持 p2p 的遗憾。而且通过 TCP/HTTP 接入的客户端都可以收发 p2p 消息。

MQTT Topic的动态特性给设计者们带来了很多发挥空间,但是有些地方需要注意:

1)名称不能带/和空格

2)短小精干,简洁明了

3)使用 UTF-8,避免不可见字符

4)在一些特殊场景里,考虑将唯一设备号嵌入到 Topic 名称,便于辨识消息发送者
比如,只有 client1 可以发布消息到client1/status, 且不能发布到client2/status,那么当你收到client1/status时,可以肯定就是client1发送的消息。

5)谨慎使用通配符#
比如,订阅 news/sport/#, 那么你就会收到下面所有这些 Topic 的消息
news/sport
news/sport/player1
news/sport/player2
news/sport/player1/score
不可预计的消息数量,会对接收端(移动端,嵌入式设备)造成负担。

6)业务可延伸
订阅关系需要事先建立,所以发送端和接收端都需要提前意识到 Topic 的存在,这就要求我们合理设计 Topic 的结构,在增加新业务需求时,适当增加子级 Topic 即可,而不用修改,甚至推翻 Topic 原先的结构。
比如,订阅李娜的新闻,可以设计成订阅 news/lina, 但是文体娱乐圈里有很多和李娜重名的,后续业务需要,用户想订阅网球李娜的新闻时,整个 Topic 结构将被迫改变,所以,在业务设计之初,尽可能在延伸性上多考虑一些。
这样设计较之前就更稳妥些:
news/sport/tennis/lina
news/sport/tennis/lina/ranking
news/sport/tennis/lina/score/australianopen

下面结合 MQ MQTT 特点,提供一个社交 IM 场景下的实现雏形,欢迎大家讨论。

准备工作:在 MQ 控制台创建父级 Topic 和 GroupID
每个设备接入 MQ MQTT 服务时,都要提供 Client ID,这是每个客户端的唯一标识,要求全局唯一。
Client ID 由两部分组成,组织形式为 GroupID@@@DeviceID。
GroupID: 需要在 MQ 控制台申请创建,用于指定一组逻辑功能完全一致的节点共用组名,代表一类相同功能的设备。
DeviceID: 每个设备独一无二的标识,由业务方自己指定,无需在 MQ 控制台创建。

我们在 MQ 控制台创建父级 Topic:IMS 和 GroupID:GID_IMS,且假设
用户A使用设备GID_IMS@@@DeviceID_A
用户B使用设备GID_IMS@@@DeviceID_B
用户C使用设备GID_IMS@@@DeviceID_C

场景1,用户A请求加用户B为好友,并进行一对一聊天

方案一,使用 p2p 消息。
优点是无需双方提前订阅(其实 p2p 功能也是通过订阅来实现的,只是用户在使用时无感知),缺点是如果DeviceID_B同时收到多个好友申请(见2),如何分辨是谁发送的请求呢?
从消息 Topic 是无法得知的,只能通过解析 message body 来辨识。

注意,p2p 消息,二级 Topic 必须是 p2p 字样,三级Topic是目标设备的 Client ID。

方案二,给每一个用户设计一个 Inbox,每个用户在客户端登录时都要订阅自己的 Inbox。
优点是每个用户收到消息时,可以通过解析 Topic 知道是谁要加他为好友,也能知道谁通过了他的好友添加请求。
当 USER B 收到消息 IMS/UserB/Inbox/Add/GFReq/UserA (见4),就知道是来自于 USER A 的好友添加请求。
当 USER A 收到消息 IMS/UserA/Inbox/Add/GFResp/UserB (见6),就知道是来自于 USER B 的反馈。

场景2,用户A关注好友B动态,B更新朋友圈,A收到更新

用户 A 想关注好友 B 的朋友圈动态,可以订阅 IMS/UserB (见1)。
好友 B 有好东东想晒一下,可以发布 IMS/UserB (见2),发布之后,所有订阅 IMS/UserB 的好友都可以看见这条分享(MQ MQTT 会负责将消息发送给所有订阅的好友)。
如果 A 不想看 B 的朋友圈动态了,那么就取消订阅 IMS/UserB (见4)。

如果是 B 不想让 A 看见自己晒的东东,该怎么办呢?
也可以利用 Inbox。
用户 A 登录时订阅 IMS/UserA/Inbox/Update/# (见2)
用户 B 发送一条消息到 IMS/UserA/Inbox/Update/UserB/Unsub (见3),A 在收到这条消息后,取消订阅 IMS/UserB (见5),在此之后,B 在朋友圈所有的分享,好友 A 都是看不到的。
当然,A 在收到 B 的取消订阅请求(见4)后,是弹窗通知到 A 本人(让 A 知晓被 B 拉黑)还是静默(A 被默默拉进 B 的黑名单),就完全由应用设计来决定了。

场景3,用户A邀请B,C好友进行群聊(B,C非好友关系)

群聊创建者 A 首先要订阅 IMS/Group123/# (见1)。
邀请用户 B, C 加入群聊,可以使用 p2p 消息(见2,4)。
用户 B, C 同意加入群聊,订阅 IMS/Group123/# (见6,7)。
加入群聊组中的成员 B 想要发言,可以携带自己的身份信息发布到 IMS/Group123/UserB (见8), 这样一来,所有订阅 IMS/Group123/# 的成员都能看到 B 的这条发言了。

场景4,逢年过节,给多个好友发送祝福信息(群发消息,不是群聊噢)

可以逐一给好友发送 p2p 消息,或者发送消息到各好友的 Inbox 中。
这种方式的缺点是需要多次 Publish,有几个好友,就需要 publish 几次(见4,6)。

不想 publish 多次,该怎么办呢?
Sorry,目前确实没有更好的办法。

其实我们希望可以创建一个虚拟 Group,好友们不用显示订阅这个 Group,由系统根据业务配置动态创建订阅关系。完成的效果是,好友们能收到发送给这个 Group 的消息,但是不会意识到这个 Group 的存在,因为客户端没有发起过订阅虚拟 Group 的动作(原理类似 p2p 订阅)。

目前 MQ MQTT 还不支持这样的功能,我们期待后续它可以提供这样功能的 Plugin,方便业务端扩展更多功能。

场景5,商业推广,系统给不同种类/定位的用户推送消息

想给不同地域的用户推送系统的新年祝福,消息的内容根据用户地域不同而变化。
正如之前的群发场景一样,使用 p2p 或者 Inbox 固然可以做到,但是整个系统,那么多用户,逐一发送并不是理想的方式。
而目前 MQ MQTT 又不支持虚拟 Group,如何完成这个功能呢?
业务设计之初,预留一个给系统广播使用的 Topic, 比如 IMS/System,每一个用户除了订阅自己的 Inbox,好友之外,也要根据自己的属地订阅系统预留的 Topic (见1,2)。
如:
北京用户订阅 IMS/System/Beijing
杭州用户订阅 IMS/System/Hangzhou

系统发送一条消息到 IMS/System/Beijing(见3), 所有北京用户都会收到(见4),系统发送一条消息到 IMS/System/Hangzhou(见5), 所有杭州用户都会收到这条消息(见6)。

用户登录客户端时,业务应用就需要预先判断其属地,并订阅相应的预留 Topic。
这种方案其实不够灵活,因为当后续扩展新业务功能时,程序需要升级(订阅新的 Topic 来满足新业务),但就目前来说,这也不失为一种可行的解决方案了。

轻量级,够灵活,开源易用,让您轻松,快速打造出一款即时通信应用APP, 心动了没?

时间: 2024-10-06 06:54:18

利用消息队列MQTT,打造一款属于自己的IM社交软件的相关文章

NetApp公司利用IBM沃森打造一款名为Elio的卡通机器人

NetApp公司也打造出了自己的Office"回形针"形象,即以IBM沃森为后端支持的Elio聊天机器人.凭借着出色的自动化与Active IQ被动/主动支持特性,其得以在NetApp产品家族当中脱颖而出. Elio是一款客户服务AI助手,负责回应用户提出的问题.凭借着IBM的沃森机器学习技术,其能够对查询内容进行分析,搜索NetApp的技术支持数据库,而后尽可能帮助客户找到正在寻求的答案. NetApp公司表示,该机器人给出答案的速度可以达到用户自行搜索支持库的四倍.不过我们目前还没

利用html5和css3打造一款创意404页面

 实现的代码 html代码:   代码如下: <svg class="me404" viewbox="0 0 1000 480"> <path id="cloud" class="st0" d="M658.4,345.2c-10.9,0-19.7-8.8-19.7-19.7c0-10.9,8.8-19.7,19.7-19.7h50.1c9.9-1.5,17.5-10,17.5-20.3 c0-11.

消息队列(MQ)重磅推出MQTT移动物联套件

消息队列(MQ)可应用在多个领域,包括异步通信解耦.企业解决方案.金融支付.电信.电子商务.快递物流.广告营销.社交.即时通信.移动应用.手游.视频.物联网.车联网等.近期,消息队列(MQ)推出顺序消息消息.MQTT移动物联套件.Kafka企业级消息服务.下述内容将解析消息队列(MQ)顺序消息.车联网.Kafka企业级消息服务的应用场景. 1. 消息类型及多种场景 消息队列支持多种消息类型: 普通消息:最大4M,消息越小,性能越高 事务消息:两阶段提交.解决分布式事务问题 定时消息:消息的延时或

流行消息队列服务

一.简单消息队列服务 HTTPSQS HTTPSQS(HTTP Simple Queue Service)是一款基于 HTTP GET/POST 协议的轻量级开源简单消息队列服务,使用 Tokyo Cabinet 的 B+Tree Key/Value 数据库来做数据的持久化存储. 队列(Queue)又称先进先出表(First In First Out),即先进入队列的元素,先从队列中取出.加入元素的一头叫"队头",取出元素的一头叫"队尾".利用消息队列可以很好地异步

OSSIM中分布式消息队列应用

 OSSIM中分布式消息队列应用   1. 消息队列处理 企业日志数量正在以指数级形式高速增长,日志数据的具有海量.多样.异构等特点,基于传统的单一节点混合式安装的OSSIM平台(指OSSIM 4.4及以下系统),无法满足海量日志分析要求.在OSSIM 4.4以后的系统中增加了中间件RabbitMQ,可通过RabbitMQ将系统中各组件解除耦合,避免了系统中运行模块的影响(例如MySQL的写操作等),这样设计可实现分布式日志分析平台的要求. OSSIM中使用RabbitMQ后,可以利用消息队列耦

分布式系统解决之道:目录、消息队列、事务系统及其他

目录服务(ZooKeeper)   分布式系统是一个由很多进程组成的整体,这个整体中每个成员部分,都会具备一些状态,比如自己的负责模块,自己的负载情况,对某些数据的掌握等等.而这些和其他进程相关的数据,在故障恢复.扩容缩容的时候变得非常重要.   简单的分布式系统,可以通过静态的配置文件,来记录这些数据:进程之间的连接对应关系,它们的IP地址和端口等等.然而,一个自动化程度高的分布式系统,必然要求这些状态数据都是动态保存的.这样才能让程序自己去做容灾和负载均衡的工作.   一些程序员会专门自己编

消息队列在测试开发中的应用思路

前言: 在面向企业级的运用中,各种中间件被广泛运用,对于多并发的应用,为了解决服务器处理性能的差异问题,普遍使用消息队列作为非实时性(或实时性)请求的转发与控制,一般可用来支持分布式请求系统.事务最终一致性,高吞吐系统,请求缓存池等架构方案. 将消息队列运用在测试工具开发过程中,带来更加健壮的服务性能以外,同时能带来更多的试用价值,本文从几个实例出发,抛砖引玉,探讨消息队列运用在测试工具开发过程中所带来的多重效益. 一:何为消息队列 1.一个人发送了一封短消息 简单的理解,消息队列就是我们通过移

消息队列在VB.NET数据库开发中的应用

数据|数据库 我们先简单的了解一下什么是消息队列(MSMQ)?消息队列是 Windows 2000(NT也有MSMQ,WIN95/98/me/xp不含消息队列服务但是支持客户端的运行)操作系统中通讯的基础,也是用于创建分布式.松散连接通讯应用程序的工具.这些应用程序可以通过不同种类的网络进行通讯,也可以与脱机的计算机通讯.消息队列分为用户创建队列和系统队列,用户队列分为: · "公共队列"在整个可传递消息的"消息队列"网络中复制并传输,并且有可能由网络连接的所有站点

如何利用AngularJS打造一款简单Web应用_AngularJS

目前不同类型的Web开发人员都在广泛使用AngularJS,这套卓越的框架也充分证明了自身满足各类不同需求的能力.作为一名Web开发人员,无论大家是刚刚入门的新手还是已经拥有丰富的实践经验,选择一款优秀的框架都是必要的工作前提,而AngularJS正是这样一套理想的解决方案.在使用AnguarJS的过程中,大家可以同时学习到更多与应用程序开发相关的知识以及如何构建起更出色.更具吸引力的应用成果.如果大家希望在应用程序的创建工作中采取各类最佳实践,那么AngularJS也能够带来极大的助益.总而言