用消息队列实现即时通讯3
Posted wavaya
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用消息队列实现即时通讯3相关的知识,希望对你有一定的参考价值。
消息队列(MQTT)
前面讨论过消息队列传输的具体内容,那我们该用哪种方式进行呢?通过查阅网络资料,发现有两个方式值得借鉴。
第一种方式每个帐号订阅自己的Inbox,而其他人都向这个Inbox发布信息,这种方式接收比较方便,但是发布时就比较麻烦。如群组有50人的话,一条消息就要发布50次,这和Http推拉信息有点类似。
第二种方式,也是我正在使用的方式。每个帐号只订阅自己的个人聊天信息,以及加入的群聊。主题以"/"进行分隔,个人聊天p2p/帐号,群聊group/组帐号。这种方式发送群消息时只用publish 到group/组帐号,避免太多群成员发布次数过多的问题,也是个人认为比较合理的方式。下面将简单演示一下个人聊天方式:
一旦登录成功,自己订阅p2p/自己帐号,
A订阅 p2p/A
B订阅 p2p/B
A对B发送聊天信息: A publish "Content" 到p2p/B
由于B已订阅p2p/B,所以B将收到 “Content"信息,
同理,B回复信息,则向 p2p/A publish "Reply",
A 收到:"Reply"
这样就完成简单的个人聊天,由于其他帐号没有订阅p2p/A,p2p/B所以也就无法接收到相应信息。当然,如果非要说其他帐号强制订阅p2p/A,p2p/B,不就能接收到他们私聊信息吗?是有这样的情况,但现在只能在客户端进行控制,强制不发生这种情况。理想的情况是订阅也要根据token进行,发布同样必须验证token,貌似阿里有带token的mqtt,没有认真研究,这些关于MQTT深入话题将要二期或三期进行研究。
这种方式群聊就比较简单,新建群group1后,A加入group1,B加入group1后,
A 订阅 group/group1
B 订阅 group/group1
A要发送信息到group1 :A publish ”content“ group/group1
A,B,以及其他人员都会收到 "content"信息,此时msgId就起到了关键性作用,由于发送都已经有了此消息,就可以通过msgId避免重复。
系统消息
首先定义系统消息主题固定格式: sys/类型[/类型结果]/帐号
因为系统消息大多都是有针对性的(广播新闻类除外,暂时没考虑这一块),比如A添加B为好友,系统会发布 添加好友信息到 sys/addP2p/B
B同意后,系统会发布 同意信息到 sys/addP2p/ok/A ,所以A和B都要订阅相关的系统主题。订阅方式:用户只需要分别订阅 sys/+/帐号,sys/+/ok/帐号,sys/+/no/帐号。
说明
为什么要订阅三个而不是订阅sys/#/帐号,因为订阅主题是用#号建议放在最后(没有强制规定,但是放在中间将忽略后面帐号),就没办法区分帐号
综上所述,当用户登录后MQTT连接成功,客户端应该向MQTT订阅:
p2p/帐号
sys/+/帐号
sys/+/ok/帐号
sys/+/no/帐号
循环参加的所有群组订阅 group/group帐号 (订阅零个或多个)
代码片段:
private static String myTopic = MessageTypes.P2P + "/" + APIX.account;
//这个表示,可能有一个,或多个情况的
private static String sysTopic = MessageTypes.SYS + "/+/" + APIX.account;
private static String sysTopicok = MessageTypes.SYS + "/+/ok/" + APIX.account;
private static String sysTopicno = MessageTypes.SYS + "/+/no/" + APIX.account;
// 订阅myTopic话题
client.subscribe(myTopic, 1);
//订阅系统消息
client.subscribe(sysTopic, 1);
client.subscribe(sysTopicok, 1);
client.subscribe(sysTopicno, 1);
if (APIX.current != null) {
List<ImGroup> groupList = APIX.current.getGroups();
if (groupList != null) {
for (ImGroup group : groupList) {
String sb = MessageTypes.GROUP + "/" + group.getAccount();
client.subscribe(sb, 1);
}
}
}
预备知识基本上将完,具体的实现将在后面进行更详细讲解。
希望大家能继续关注后期文章,下一期专门讲解消息队列相关内容
请关注公众号有更多精彩等你:
以上是关于用消息队列实现即时通讯3的主要内容,如果未能解决你的问题,请参考以下文章