tigase摸索 IM服务器

刚接触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 


tigase摸索 IM服务器_第1张图片

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: 查询和响应中出现的错误。

http://www.baidu.com/#wd=xmpp%20message%E2%80%9D%EF%BC%8C%E2%80%9Cpresence%E2%80%9D%E5%92%8C%E2%80%9Ciq%E2%80%9D&tn=baidu&ie=utf-8&f=8&rsv_bp=1&rsv_sug3=3&rsv_sug4=50&rsv_sug1=1&rsv_n=2&inputT=593&rsv_sug=2&bs=xmpp&rsv_spt=3


XMPP通信原语有3种:message、presence和iq。
5.1 message
message是一种基本推送消息方法,它不要求响应。主要用于IM、groupChat、alert和notification之类的应用中。
主要 属性如下:
5.1.1  type属性,它主要有5种类型:
  • normal:类似于email,主要特点是不要求响应;
  • chat:类似于qq里的好友即时聊天,主要特点是实时通讯;
  • groupchat:类似于聊天室里的群聊;
  • headline:用于发送alert和notification;
  • error:如果发送message出错,发现错误的实体会用这个类别来通知发送者出错了;
5.1.2  to属性:标识消息的接收方。
5.1.3  from属性:指发送方的名字或标示。为防止地址外泄,这个地址通常由发送者的server填写,而不是发送者。

载荷(payload):例如body,subject

例子:
<message 
  to="[email protected]/contact" 
  type="chat" >
    <body> 你好,在忙吗</body>
</message>

5.2 presence
presence用来表明用户的状态,如:online、away、dnd(请勿打扰)等。当改变自己的状态时,就会在stream的上下文中插入一个Presence元素,来表明自身的状态。要想接受presence消息,必须经过一个叫做presence subscription的授权过程。
5.2.1 属性
5.2.1.1 type属性,非必须。有以下类别
  • subscribe:订阅其他用户的状态
  • probe:请求获取其他用户的状态
  • unavailable:不可用,离线(offline)状态
5.2.1.2 to属性:标识消息的接收方。
5.2.1.3 from属性:指发送方的名字或标示。

5.2.2 载荷(payload):
5.2.2.1 show:
  • chat:聊天中
  • away:暂时离开
  • xa:eXtend Away,长时间离开
  • dnd:勿打扰
5.2.2.2 status:格式自由,可阅读的文本。也叫做rich presence或者extended presence,常用来表示用户当前心情,活动,听的歌曲,看的视频,所在的聊天室,访问的网页,玩的游戏等等。
5.2.2.3 priority:范围-128~127。高优先级的resource能接受发送到bare JID的消息,低优先级的resource不能。优先级为负数的resource不能收到发送到bare JID的消息。

例子:
<presence from="[email protected]/pda">
  <show>xa</show>
  <status>down the rabbit hole!</status>
</presence>

5.3 iq (Info / Query)
一种请求/响应机制,从一个实体从发送请求,另外一个实体接受请求,并进行响应。例如,client在stream的上下文中插入一个元素,向Server请求得到自己的好友列表,Server返回一个,里面是请求的结果。
主要的属性是type。包括:
  • Get :获取当前域值。类似于http get方法。
  • Set :设置或替换get查询的值。类似于http put方法。
  • Result :说明成功的响应了先前的查询。类似于http状态码200。
  • Error: 查询和响应中出现的错误。
例子:
<iq from="[email protected]/pda" 
    id="rr82a1z7"
    to="[email protected]
    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是不一样的

tigase摸索 IM服务器_第2张图片


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:

  1. virtual host names this is a hostname (domain) visible to your users like jabber.orgcompany.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
  2. 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.netnode2.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

你可能感兴趣的:(IM,XMPP)