刚接触tigase,对刚接触的概念和基础做个记录
XMPP(http://xmpp.org/)
XMPP(Extensible Messaging and Presence Protocol,前称Jabber[1])是一种以XML为基础的开放式实时通信协议,是经由互联网工程工作小组(IETF)通过的互联网标准。XMPP因为被Google Talk应用而被广大网民所接触.http://zh.wikipedia.org/wiki/XMPP
协议介绍:http://blog.csdn.net/wbw1985/article/details/5502272
上有xmpp的服务端和客户端http://xmpp.org/xmpp-software/servers/
XEPs(XMPP Extension Protocols),扩展协议
一个XMPP客户端需要实现的基本的XEP供参考。(http://blog.csdn.net/tjsjping/article/details/6835975)
XMPP SASL TSL
RFC(Request For Comments)
征求修正意见书(英语:Request For Comments,缩写为 RFC),是由互联网工程任务组(IETF)发布的一系列备忘录。文件收集了有关互联网相关信息,以及UNIX和互联网社区的软件文件,以编号排定。目前RFC文件是由互联网协会(ISOC)赞助发布
http://zh.wikipedia.org/wiki/RFC
BOSH
BOSH (Bidirectional-streams Over Synchronous HTTP)是一种在客户端和服务器端之间通过HTTP的请求/响应进行客户端和服务器双向通信的技术,BOSH在XMPP系列规范中的XEP-0124中定义,应用场合为基于浏览器的客户端访问XMPP服务器。 下面的内容来自XEP-0124规范。http://www.xmpp.org/extensions/xep-0124.html
http://shallon.iteye.com/blog/126428
开发的话,看develop guide开发文档
http://www.tigase.org/devel-guide
Tigase版本解释
Starting from version 5.2.0 there will be two separate archives:
minimal version (-dist) containing only tigase-server, tigase-xmltools and tigase-utils
max version (-dist-max) containing all additional tigase components (MUC, PubSub, HTTP API, OSGi support, etc.) as well as dependencies required by those components.
http://www.tigase.org/content/tigase-xmpp-server-520-and-later-compilation-and-generating-distribution-packages
tigase实现的XEPS和RFC
http://www.tigase.org/tigase-server-features
openfire实现的XEPS和RFC
http://www.igniterealtime.org/builds/openfire/docs/latest/documentation/protocol-support.html
Top Ten Ways to Customize Tigase
http://www.dynamicalsoftware.com/news/?p=195
tigase-auth sasl 开发例子
https://github.com/Smartupz/tigase-oauth
什么是IQ
IQ的意思是Info/Query:它是一种请求和应答机制,和http有一些类似的地方。 IQ的语意允许一个实体向另一个实体发送请求,并从另一个实体获取应答。请求和应答当中的数据在IQ元素的第一级子节点(命名空间的声明)当中被定义,请求方实体可以通过id标签来跟踪交互过程。如此一来,IQ交互的数据交换模式就类似于“get/result” 或者 “set/result”(在某些情况下,也可能是get/error和set/error)。如有困惑请参考XMPP官方英文文档:
http://xmpp.org/rfcs/rfc3920.html#stanzas-semantics-iq
http://my.oschina.net/greki/blog/209588
下载源码,如果没git,用svn
svn co https://svn.tigase.org/reps/tigase-server/trunk/ tigase-server
注意:svn 和git的版本是不一致的
xmpp3个顶层XML元素: Message、Presence、IQ
Message
用于在两个jabber用户之间发送信息。Jsm(jabber会话管理器)负责满足所有的消息,不管目标用户的状态如何。如果用户在线jsm立即提交;否则jsm就存储。
To :标识消息的接收方。
from : 指发送方的名字或标示(id)o
Text: 此元素包含了要提交给目标用户的信息
<Presence>
用来表明用户的状态,如:online、away、dnd(请勿打扰)等。当用户离线或改变自己的状态时,就会在stream的上下文中插入一个Presence元素,来表明自身的状态.结构如下所示:
< IQ >
一种请求/响应机制,从一个实体从发送请求,另外一个实体接受请求,并进行响应.例如,client在stream的上下文中插入一个元素,向Server请求得到自己的好友列表,Server返回一个,里面是请求的结果.
<iq > 主要的属性是type。包括:
Get :获取当前域值。
Set :设置或替换get查询的值。
Result :说明成功的响应了先前的查询。
Error: 查询和响应中出现的错误。
- normal:类似于email,主要特点是不要求响应;
- chat:类似于qq里的好友即时聊天,主要特点是实时通讯;
- groupchat:类似于聊天室里的群聊;
- headline:用于发送alert和notification;
- error:如果发送message出错,发现错误的实体会用这个类别来通知发送者出错了;
to="lily@jabber.org/contact"
type="chat" >
<body> 你好,在忙吗</body>
</message>
- subscribe:订阅其他用户的状态
- probe:请求获取其他用户的状态
- unavailable:不可用,离线(offline)状态
- chat:聊天中
- away:暂时离开
- xa:eXtend Away,长时间离开
- dnd:勿打扰
<show>xa</show>
<status>down the rabbit hole!</status>
</presence>
主要的属性是type。包括:
- Get :获取当前域值。类似于http get方法。
- Set :设置或替换get查询的值。类似于http put方法。
- Result :说明成功的响应了先前的查询。类似于http状态码200。
- Error: 查询和响应中出现的错误。
id="rr82a1z7"
to="alice@wonderland.lit"
type="get">
<query xmlns="jabber:iq:roster"/>
</iq>
plugin and component
from what I can tell a component is fired up by the MessageRouter (?) and a plug-in is instantiated by the SessionManager (which itself is a component, which reads all incoming traffic).
plugin是session manager的,是基于xmpp的标签来进行处理,
component处理,是被MessageRouter根据它的component jid 选择进行处理
http://www.tigase.org/content/breaking-point-between-component-and-plug
sm c2s s2s
- sm - session manager component.
- c2s - client connection manager component
- s2s - server connection manager component
- ext2s - external component connection manager
- ssender - StanzaSender component
源码 tigase packet 的from jid 和to jid 和xmpp协议的jid是不一样的
Packet解析
.XMPPIOService.processSocketData() {
Packet pack = Packet.packetInstance(elem);
}
添加receivedPackets.offer(packet)到队列
ClientConnectionManager.processSocketData处理队
public Queue<Packet> processSocketData(XMPPIOService<Object> serv)
// p.setPacketFrom(getFromAddress(id));
p.setPacketFrom(id);
JID receiver = serv.getDataReceiver();
if (receiver != null) {
p.setPacketTo(serv.getDataReceiver());
addOutPacket(p);
} else {
tigase.util.RoutingsContainer.MultiMode.computeRouting(String address)
public String computeRouting(final String address) {
if (address == null) {
if (log.isLoggable(Level.FINER)) {
log.finer("For null address returning default routing: " + def);
}
return def;
} // end of if (address == null)
for (Map.Entry<Pattern, String> entry: routings.entrySet()) {
if (entry.getKey().matcher(address).find()) {
if (log.isLoggable(Level.FINEST)) {
log.finest("For address: " + address + " pattern: "
+ entry.getKey().pattern() + " matched.");
}
return entry.getValue();
} // end of if (pattern.matcher(address).find())
} // end of for ()
return def;
}
public String computeRouting(final String address) {
if (address == null) {
if (log.isLoggable(Level.FINER)) {
log.finer("For null address returning default routing: " + def);
}
return def;
} // end of if (address == null)
for (Map.Entry<Pattern, String> entry: routings.entrySet()) {
if (entry.getKey().matcher(address).find()) {
if (log.isLoggable(Level.FINEST)) {
log.finest("For address: " + address + " pattern: "
+ entry.getKey().pattern() + " matched.");
}
return entry.getValue();
} // end of if (pattern.matcher(address).find())
} // end of for ()
return def;
}
ConnectionManager
500行 serv.setDataReceiver(JID.jidInstanceNS(routings.computeRouting(hostname)));
IOService
domain vhost vitual host 集群
http://www.tigase.org/content/clustering-tigase-42
There are 2 types of DNS names used in your XMPP cluster:
- virtual host names this is a hostname (domain) visible to your users like jabber.org, company.com and so on. Your whole cluster, regardless how many nodes you have is visible to users as one server working for this virtual domain. This is defined by --virt-hosts property in the init.properties file. And you can have as many as you like virtual hosts for your XMPP installation. If you query DNS for your virtual domain it should return an IP address of one of the cluster nodes. Every time you query DNS it may return a different IP address (IP address of a different cluster node). This is your example.com
- real host names are names unique to each of the cluster node. They are not related to virtual names and they can have a form - node1.internal.net, node2.spare.internal.net and so on. These are your mc1 and mc2. They are normally not visible to your users and they are only used internally by the Tigase cluster nodes. The important thing is that if you query DNS for the node hostname mc1 it must always return one and the same IP address of the proper cluster node. This is what you put to --cluster-nodes property in the init.properties file.
gc优化,参考注释
http://www.tigase.org/content/how-packets-are-processed-sm-and-plugins
I personally recommend to use concurrent Mark Sweep and incremental mode GC which runs GC in background whenever possible.
Configuration wizards
配置向导
http://www.tigase.org/node/173
离线消息处理
https://projects.tigase.org/projects/tigase-server/repository/entry/trunk/src/main/java/tigase/xmpp/impl/OfflineMessages.java