看郭林的xmpp讲解笔记:http://www.imooc.com/video/5248
xmpp(Extensible Messaging and Presence Protocol)可扩展消息和展示协议,是一种以xml为基础的开放式实时通信协议,它将需要实时通信的消息嵌入到xml结构体当中,不仅具有很好的可扩展性,还拥有较强的可读性。
我们所熟知的Email就是用xmpp协议,不同的邮箱可以互发消息就是因为使用的统一的协议。
xmpp协议可以用来实现IM,谷歌的Gtalk就是用的xmpp协议,国内的腾讯用的是自己的协议实现的IM所以没有办法和别的IM平台互发消息。
xmpp协议的优点
开放性
在客户端,服务器,开源库都有了很多现成的实现
标准性
已经被定义为IM即时通信的标准,规范,任何实现xmpp协议的IM平台都可以和Gtalk消息互通。
可扩展
xmpp协议是用xml格式的上下文结构的,在核心协议的基础上轻松扩展各种功能
跨平台
不限定开发语言,不限定任何环境,任何操作系统都可以使用xmpp协议进行编程的。
xmpp协议的缺点
数据冗余
有开始标签就要对应结束标签,在移动端产生不必要的流量。
不支持二进制数据(只限定文本数据,专注于消息传输),要传递别的格式(图片,视频)可以结合其他的协议共同完成。
xmpp基础知识
Xml Stanzas
<stream:stream>
...
<presence>
<show/>
</presence>
<message to='foo'>
<body/>
</message>
<iq to='bar'>
<query/>
</iq>
...
</stream:stream>
XMPP的身份标识
XMPP规定,每个客户端是使用JID来作为身份标识的:
[user”@”]domain[“/”resource]
用户名@域名/pc/android/ios
XML Stanza通用属性
from:服务器通常不会信任from指定的内容,不然就会存在客户端伪造另一个用户发送消息,服务器会根据连接的状态自动判断这条消息是由谁发出的。可以加和不加,更多的作用是调试的时候分析问题的原因。
to:这条消息是发送给谁的。服务端会解析这里的值,将消息转发给指定的用户。如果没有指定to,服务器会认为是消息是发给自己的,会内部处理。
type:指定Stanza的类型。
id:对一段Stanza做唯一标识符的。比如客户端发送一段Stanza给服务器指定了唯一id,服务器响应一段Stanza给客户端也带上了相同的id。这样客户端就知道服务端响应的是刚才那一段Stanza。
stream结构
Client:发送
〈stream:stream
to="example.com
xmlns="jabber:client"
xmlns:stream="http://etherx.jabber.org/streams"
version="1.0">
Server:响应
〈stream:stream
from="example.com"
id="someid"
xmlns="jabber:client"
xmlns:stream="http://etherx.jabber.org/streams"
version="1.0">
presence结构
jackson@gmail.com用户告诉jimmy@msn.com
unavailable下线了
<presence
from="jackson@gmail.com"
to="jimmy@msn.com"
type="unavailable"/>
type可选参数
available 上线
unavailable 下线
subscribe 订阅某个用户的在线状态
subscribed 授权给该次订阅
unsubscribe 取消订阅某个用户的在线状态
unsubscribed 授权取消该次订阅
error 发生错误
<presence>
<show>away</show>
<status>Having a spot of tea</status>
</presence>
show可选参数
1.chat:在线,可聊天
2.away:短时间暂离状态
3.xa:长时间离开,外出就餐
4.dnd:不想被打扰
message结构
<message
from="jackson@gmail.com"
to="jimmy@msn.com"
type="chat">
<body>Hello!</body>聊天的主题内容
</message>
type可选参数
normal 独立消息,不属于任何会话,默认的type类型
chat 表示一对一的会话
groupchat 表示群聊会话
headline 客户端显示的头条内容,为了引起用户注意
error 出现的错误
IQ结构(InfoQuery)
〈iq
from="jackson@gmail.com"
id="rr82a1z7"
to="jackson@gmail.com"
type="get">
〈query xmlns="jabber:iq:roster" />获取自己的联系人列表
</iq>
type可选参数:
get :类似http中的get
set :类似http中的post
result :响应数据
error :发生了错误
〈iq
from="jackson@gmail.com"
id="rr82a1z7" //id必须和请求iq的id一致
to="jackson@gmail.com"
type="result">
〈query xmlns="jabber:iq:roster">获取自己的联系人列表
<item jid="jimmy@msn.com" />
<item jid="tom@hotmail.com" />
</query>
</iq>