Tigase 发送消息的流程源码分析

本文深入解析Tigase服务器中消息传递的流程,包括从客户端发送到服务端,再到目标组件的每一步处理,涉及ClientConnectionManager、SessionManager、MessageRouter等组件的交互,以及消息在XMPP框架下的类型和属性。通过对源码的分析,揭示了Tigase如何确保消息的安全传输和正确路由。
摘要由CSDN通过智能技术生成

XMPP 的节是使用基本的”push”方法来从一个地方到另一个地方得到消息。因为消息通常是不告知的,它们是一种”fire-and-forget”(发射后自寻目的)的机制来从一个地方到另一个地方快速获取信息
消息节有五种不同的类型,通过 type 属性来进行区分:例如 chat 类型为 chat 的消息在两个实体间的实时对话中交换,例如两个朋友之间的即时通讯聊天。除了 type 属性外,消息节还包括一个 to 和 from 地址,并且也可以包含一个用于跟踪目的的 id 属性(我们在使用更为广泛的 IQ 节中详细的讨论 IDs)。to 地址是预期接收人的
JabberID,from 地址是发送者的JabberID。from 地址不由发送客户端提供,而是由发送者的服务器添加邮戳,以避免地址欺骗。
例如最著名的组件的一个例子是MUC或PubSub。在Tigase中,几乎所有东西实际上都是一个组件:会话管理器、s2s连接管理器、消息路由器等等,组件是根据服务器配置加载的,新的组件可以在运行时加载和激活。您可以轻松地替换组件实现,唯一要做的更改是配置条目中的类名。

Tigase 中定义一个最简单的消息组件,需要实现MessageReceiver或继承 extends AbstractMessageReceiver 类, MessageReceiver 的抽象类: AbstractMessageReceiver 子类 :
一、ClientConnectionManager
二、SessionManager
三、 MessageRouter

public void setProperties(Map<String, Object> props){
for (String name : msgrcv_names) {
mr = conf.getMsgRcvInstance(name);
if (mr instanceof MessageReceiver) {
((MessageReceiver) mr).setParent(this);
((MessageReceiver) mr).start();
}
}
}
1、当客户端发送的message消息到tigase服务端,每个一SOCKET连接都会被包装成IOService对象,IOService包含一系列操作socket的方法(接收发送数据等),processSocketData()接收网络数据,由tigase.net处理解析成xml对象,并将packet放到接收队列receivedPackets中再调用serviceListener.packetsReady(this)。由于ConnectionManager实现IOServiceListener接口,实现上调用的的是ConnectionManager中的packetsReady()来开始处理数据

此时的packet :packetFrom=null,packetTo=null。

ClientConnectionManager.processSocketData方法中设置packet的一些属性:
此时: packetFrom=c2s@llooper/192.168.0.33_5222_192.168.0.33_38624, packetTo=sess-man@llooper
ClientConnectionManager.processSocketData(XMPPIOServiceserv)
JID id = serv.getConnectionId(); //c2s@llooper/192.168.0.33_5222_192.168.0.33_38624
p.setPacketFrom(id); //packetFrom 设置为onnectionId
p.setPacketTo(serv.getDataReceiver()); //packetTo 设置为sess-man --> SessionManager
addOutPacket§;//将会委托给父 MessageRouter 路由

}
//packet 被设置上一些源信息,和目的地信息,接下来,这个数据包将会委托给父 MessageRouter 帮忙路由到 SessionManager组件中进行处理
packet = (tigase.server.Message) from=c2s@llooper/192.168.0.33_5222_192.168.0.33_38624, to=sess-man@llooper, DATA=SWjZv5, SIZE=170, XMLNS=jabber:client, PRIORITY=NORMAL, PERMISSION=NONE, TYPE=chat

packet = from=c2s@llooper/192.168.0.33_5222_192.168.0.33_38624, to=sess-man@llooper, DATA=7VKMRq, SIZE=168, XMLNS=jabber:client, PRIORITY=NORMAL, PERMISSION=NONE, TYPE=chat

2、MessageRouter.processPacket(Packet packet)部分代码如下:

复制代码
//我们不会处理没有目标地址的数据包,只是丢弃它们并写一个日志消息
if (packet.getTo() == null) {
log.log(Level.WARNING, “Packet with TO attribute set to NULL: {0}”, packet);
return;
}

//它不是一个服务发现包,我们必须找到一个处理组件
//下面的代码块是“快速”找到一个组件if

//这个包TO 组件ID,格式在以下一项:
// 1。组件名+“@”+默认域名
// 2。组件名+“@”+任何虚拟主机名
// 3。组件名+ “.”+默认域名
// 4。组件名+ “.”+任何虚拟主机名

ServerComponent comp = getLocalComponent(packet.getTo()); //SessionManager
comp.processPacket(packet, results);
复制代码
3、SessionManager.processPacket(final Packet packet)处理,有要代码如下。 例如A->B,这样做的目的是为了首先确定用户A有权限发送packet,然后是确定用户B有权限接收数据。如果用户B不在线,那么离线消息处理器会把packet保存到数据库当中。

复制代码
//XMPPResourceConnection session——用户会话保存所有用户会话数据,并提供对用户数据存储库的访问。它只允许在会话的生命周期内将信息存储在永久存储或内存中。如果在分组处理时没有联机用户会话,则此参数可以为空。
XMPPResourceConnection conn = getXMPPResourceConnection(packet);
/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值