标签:
本文介绍XMPP协议原理及相关信息。
XMPP协议简介
XMPP(Extensible Messageing and Presence Protocol:可扩展消息与存在协议)是目前主流的四种IM(IM:instant messaging,即时消息)协议之一,其他三种分别为:即时信息和空间协议(IMPP)、空间和即时信息协议(PRIM)、针对即时通讯和空间平衡扩充的进程开始协议SIP(SIMPLE)。
在这四种协议中,XMPP是最灵活的。XMPP是一种基于XML的协议,它继承了在XML环境中灵活的发展性。因此,基于XMPP的应用具有超强的可扩展性。经过扩展以后的XMPP可以通过发送扩展的信息来处理用户的需求,以及在XMPP的顶端建立如内容发布系统和基于地址的服务等应用程 序。而且,XMPP包含了针对服务器端的软件协议,使之能与另一个进行通话,这使得开发者更容易建立客户应用程序或给一个配好系统添加功能。
1. 什么是XMPP ?
XMPP的前身是Jabber,一个开源形式组织产生的网络即时通信协议。XMPP目前被IETF国际标准组织完成了标准化工作。标准化的核心结果分为两部分; 核心的XML流传输协议 基于XML流传输的即时通讯扩展应用 XMPP的核心XML流传输协议的定义使得XMPP能够在一个比以往网络通信协议更规范的平台上。借助于XML易于解析和阅读的特性,使得XMPP的协议能够非常漂亮。 XMPP的即时通讯扩展应用部分是根据IETF在这之前对即时通讯的一个抽象定义的,与其他业已得到广泛使用的即时通讯协议,诸如AIM,QQ等有功能完整,完善等先进性。
2. XMPP的基本网络结构是怎样的?
XMPP中定义了三个角色,客户端,服务器,网关。通信能够在这三者的任意两个之间双向发生。服务器同时承担了客户端信息记录,连接管理和信息的路由功能。网关承担着与异构即时通信系统的互联互通,异构系统可以包括SMS(短信),MSN,ICQ等。基本的网络形式是单客户端通过TCP/IP连接到单服务器,然后在之上传输XML。
3. XMPP通过TCP传什么了?
传输的是与即时通讯相关的指令。在以前这些命令要么用2进制的形式发送(比如QQ),要么用纯文本指令加空格加参数加换行苻的方式发送(比如MSN)。而XMPP传输的即时通讯指令的逻辑与以往相仿,只是协议的形式变成了XML格式的纯文本。这不但使得解析容易了,人也容易阅读了,方便了开发和查错。而XMPP的核心部分就是一个在网络上分片断发送XML的流协议。这个流协议是XMPP的即时通讯指令的传递基础,也是一个非常重要的可以被进一步利用的网络基础协议。所以可以说,XMPP用TCP传的是XML流。
XMPP协议工作原理:
4. XMPP协议地址格式:
5. XMPP消息格式:
6. 核心的XML流传输协议
基于XML FreeEIM流传输的即时通讯扩展应用
XMPP的核心XML流传输协议的定义使得XMPP能够在一个比以往网络通信协议更规范的平台上。借助于XML易于解析和阅读的特性,使得XMPP的协议能够非常漂亮。
XMPP的即时通讯扩展应用部分是根据IETF在这之前对即时通讯的一个抽象定义的,与其他业已得到广泛使用的即时通讯协议,诸如AIM,QQ等有功能完整,完善等先进性。
XMPP的扩展协议Jingle使得其支持语音和视频。
XMPP的官方文档时RFC 3920.
7. XMPP应用示例
举个例子看看所谓的XML流是什么样子的?
以文档的观点来看,客户端或服务器发送的所有XML文本连缀在一起,从<stream>到</stream>构成了一个完整的XML文档。其中的stream标签就是所谓的XML Stream。在<stream>与</stream>中间的那些<message>...</message>这样的XML元素就是所谓的XML Stanza(XML节)。XMPP核心协议通信的基本模式就是先建立一个stream,然后协商一堆安全之类的东西,中间通信过程就是客户端发送XML Stanza,一个接一个的。服务器根据客户端发送的信息以及程序的逻辑,发送XML Stanza给客户端。但是这个过程并不是一问一答的,任何时候都有可能从一方发信给另外一方。通信的最后阶段是</stream>关闭流,关闭TCP/IP连接。
8. XMPP系统特点:
1)客户机/服务器通信模式;(2)分布式网络;(3)简单的客户端;(4)XML的数据格式。
9.通俗解释:
其实XMPP 是一种很类似于http协议的一种数据传输协议,它的过程就如同“解包装--〉包装”的过程,用户只需要明白它接受的类型,并理解它返回的类型,就可以很好的利用xmpp来进行数据通讯。
最后,希望转载的朋友能够尊重作者的劳动成果,加上转载地址:http://www.cnblogs.com/hanyonglu/archive/2012/03/04/2378956.html 谢谢。
#import "ViewController.h"
#import "XMPPFramework.h"
#define HOST @"1000phone.net"
@interface ViewController ()<XMPPStreamDelegate>{
IBOutlet UITextField* _nameField;
IBOutlet UITextField* _passwordField;
IBOutlet UITextField* _friendField;
IBOutlet UITextField* _textField;
XMPPStream* _stream;
}
- (IBAction)reg:(id)sender;
- (IBAction)login:(id)sender;
- (IBAction)addFriend:(id)sender;
- (IBAction)sendText:(id)sender;
- (IBAction)getFriendList:(id)sender;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
_stream = [[XMPPStream alloc] init];
[_stream setHostName:HOST];
[_stream addDelegate:self delegateQueue:dispatch_get_main_queue()];
}
//上线
- (void)goOnline{
//<presence/>
XMPPPresence* presence = [XMPPPresence presence];
[_stream sendElement:presence];
}
//下线
- (void)goOffline{
//<presence type="unavailable"/>
XMPPPresence* presence = [XMPPPresence presenceWithType:@"unavailable"];
[_stream sendElement:presence];
[_stream disconnect];
}
//注册
- (IBAction)reg:(id)sender{
//如果已经连接,先断开
if (_stream.isConnected) {
[self goOffline];
}
[_stream setMyJID:[XMPPJID jidWithString:[NSString stringWithFormat:@"%@@%@", _nameField.text, HOST]]];
_stream.tag = @"注册";
[_stream connectWithTimeout:30 error:nil];
}
//登陆
- (IBAction)login:(id)sender{
//如果已经连接,先断开
if (_stream.isConnected) {
[self goOffline];
}
//设置要登陆的jid
[_stream setMyJID:[XMPPJID jidWithString:[NSString stringWithFormat:@"%@@%@", _nameField.text, HOST]]];
_stream.tag = @"登陆";
//连接
[_stream connectWithTimeout:30 error:nil];
}
//添加好友
- (IBAction)addFriend:(id)sender{
/*
<presence type="subscribe" to="好友jid"/>
*/
XMPPPresence* presence = [XMPPPresence presenceWithType:@"subscribe" to:[XMPPJID jidWithString:[NSString stringWithFormat:@"%@@%@", _friendField.text, HOST]]];
[_stream sendElement:presence];
}
//接收好友请求
- (void)xmppStream:(XMPPStream *)sender didReceivePresence:(XMPPPresence *)presence{
//判断是否是一个好友请求
if ([presence.type isEqualToString:@"subscribe"]) {
//同意好友请求
XMPPPresence* pre = [XMPPPresence presenceWithType:@"subscribed" to:presence.from];
[_stream sendElement:pre];
}
//判断是否添加成功
if ([presence.type isEqualToString:@"subscribed"]) {
NSLog(@"添加好友 %@ 成功", presence.fromStr);
}
NSLog(@"%@", presence.type);
}
//好友列表
- (IBAction)getFriendList:(id)sender{
/*
<iq type="get" id="roster">
<query xmlns="jabber:iq:roster"/>
</iq>
*/
XMPPIQ* iq = [XMPPIQ iqWithType:@"get"];
[iq addAttributeWithName:@"id" stringValue:@"roster"];
NSXMLElement* query = [NSXMLElement elementWithName:@"query" xmlns:@"jabber:iq:roster"];
[iq addChild:query];
[_stream sendElement:iq];
}
//接收好友列表
- (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq{
/*
<iq>
<query>
<item jid=""/>
<item jid=""/>
<item jid=""/>
</query>
</iq>
*/
NSXMLElement* query = iq.children[0];
for (NSXMLElement* item in query.children) {
NSLog(@"%@", item.XMLString);
}
return YES;
}
//发送消息
- (IBAction)sendText:(id)sender{
/*
<message to="老郭" type="chat">
<body>
老严吃醋了。
</body>
</message>
*/
XMPPMessage* message = [XMPPMessage messageWithType:@"chat" to:[XMPPJID jidWithString:[NSString stringWithFormat:@"%@@%@", _friendField.text, HOST]]];
NSXMLElement* body = [NSXMLElement elementWithName:@"body" stringValue:_textField.text];
[message addChild:body];
[_stream sendElement:message];
}
//接收消息
- (void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message{
NSLog(@"%@:%@", message.fromStr, message.stringValue);
}
//连接成功
- (void)xmppStreamDidConnect:(XMPPStream *)sender{
NSLog(@"连接成功");
//注册
if ([sender.tag isEqualToString:@"注册"]) {
[_stream registerWithPassword:_passwordField.text error:nil];
}
//登陆
if ([sender.tag isEqualToString:@"登陆"]) {
[_stream authenticateWithPassword:_passwordField.text error:nil];
}
}
//登陆成功
- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender{
NSLog(@"登陆成功");
[self goOnline];
}
//注册成功
- (void)xmppStreamDidRegister:(XMPPStream *)sender{
NSLog(@"注册成功");
}
@end
标签:
原文地址:http://www.cnblogs.com/wxw511518/p/4446850.html