IOS-XMPP

一、即时通讯技术简介

即时通讯技术(IM -- Instant Messaging)支持用户在线实时交谈。如果要发送一条信息,用户需要打开一个小窗口,以便让用户及其朋友在其中输入信息并让交谈双方都看到交谈的内容
 
有许多的IM系统,如AOL、Yahoo IM、 MSN以及QQ,它们最大的区别在于各自通讯协议的实现,所以即时通讯技术的核心在于它的传输协议
 
协议用来说明信息在网络上如何传输,如果有了统一的传输协议,那么应当可以实现各个IM之间的直接通讯,为了创建即时通讯的统一标准,目前已经出现过的IM协议包括:IETF的对话初始协议(SIP)和即时通讯对话初始协议和表示扩展协议(SIMPLE)、应用交换协议(APEX)、显示和即时通讯协议(PRIM)及基于XML且开放的可扩展通讯和表示协议(XMPP)协议(常称为 Jabber 协议)
 
人们多次努力,试图统一各大主要IM供应商的标准(AOL、Yahoo 及 Microsoft),但无一成功,且每一种IM仍然继续使用自己所拥有的协议
 
二、XMPP起源
XMPP是基于XML的协议,用于即时消息(IM)以及在线现场探测。最初,XMPP作为一个框架开发,目标是支持企业环境内的即时消息传递和联机状态应用程序。
XMPP前身是Jabber(1998年),是一个开源组织定义的网络即时通信协议
 
XMPP是一个分散型通信网络,这意味着,只要网络基础设施允许,任何XMPP用户都可以向其他任何XMPP用户传递消息。多个XMPP服务器也可以通过一个专门的“服务器-服务器”协议相互通信,提供了创建分散型社交网络和协作框架的可能性
 
尽管XMPP的出现是为了满足“个人-个人”即时消息传递的要求,但它完全不必局限于此任务

三、XMPP 简介

XMPP是一种基于XML的协议,它继承了在XML环境中灵活的发展性。这表明XMPP是可扩展的。可以通过发送扩展的信息来处理用户的需求,以及在 XMPP的顶端建立如内容发布系统和基于地址的服务等应用程序。而且,XMPP包含了针对服务器端的软件协议,使之能与另一个进行通话,这使得开发者更容易建立客户应用程序或给一个配置好的系统添加功能
XMPP的核心XML流传输协议的定义使得XMPP能够在一个比以往网络通信协议更规范的平台上。借助于XML易于解析和阅读的特性,使得XMPP的协议能够非常漂亮
XMPP的即时通讯扩展应用部分是根据IETF在这之前对即时通讯的一个抽象定义的,与其他业已得到广泛使用的即时通讯协议,诸如AIM,QQ等有功能完整,完善等先进性
XMPP的扩展协议Jingle使得其支持语音和视频,目前iOS尚不支持
XMPP的官方文档是RFC 3920
XMPP协议曾经是Google力推的即时通信协议,其代表作品是GTalk
 
四、XMPP定义
XMPP:The Extensible Messaging and Presence Protocol(可扩展通讯和表示协议)
 
XMPP可用于服务类实时通讯、表示和需求响应服务中的XML数据元流式传输。XMPP以Jabber协议为基础,而Jabber是即时通讯中常用的开放式协议
 
XMPP是基于XML的协议,用于即时消息(IM)以及在线现场探测。促进服务器之间的准即时操作。这个协议可能最终允许因特网用户向因特网上的其他任何人发送即时消息,即使其操作系统和浏览器不同
 
五、XMPP的基本结构
XMPP是一个典型的C/S架构,而不是像大多数即时通讯软件一样,使用P2P客户端到客户端的架构,也就是说在大多数情况下,当两个客户端进行通讯时, 他们的消息都是通过服务器传递的。采用这种架构,主要是为了简化客户端,将大多数工作放在服务器端进行
 
XMPP中定义了三个角色,客户端,服务器,网关。通信能够在这三者的任意两个之间双向发生
 
服务器同时承担了客户端信息记录,连接管理和信息的路由功能
网关承担着与异构即时通信系统的互联互通,异构系统可以包括SMS(短信),MSN,ICQ等
 
基本的网络形式是单客户端通过TCP/IP连接到单服务器,然后在之上传输XML流

六、XMPP工作原理

1.节点连接到服务器
2.服务器利用本地目录系统中的证书对其认证
3.节点指定目标地址,让服务器告知目标状态
4.服务器查找、连接并进行相互认证
5.节点之间进行交互
 
七、XMPP 传输内容
XMPP应用传输的是与即时通讯相关的指令。在以前这些命令要么用二进制的形式发送(比如QQ),要么用纯文本指令加空格加参数加换行符的方式发送(比如MSN)
 
而XMPP传输的即时通讯指令的逻辑与以往相仿,只是协议的形式变成了XML格式的纯文本。这不但使得解析容易了,人也容易阅读了,方便了开发和查错
 
而XMPP的核心部分就是一个在网络上分片段发送XML的流协议。这个流协议是XMPP的即时通讯指令的传递基础,也是一个非常重要的可以被进一步利用的网络基础协议,可以说XMPP用TCP传的是XML流
 
八、XMPP 优缺点
优点
开放
标准(XMPP的技术规格已被定义在RFC 3920及RFC 3921)
证实可用,谷歌证实了GTalk
分散
安全
可扩展
 
缺点
数据负载过重XML
没有二进制传输
 
九、XMPP 传输小结
XMPP是一种类似于HTTP协议的一种数据传输协议,其过程就如同“解包装--〉包装”的过程。只需要理解其接收的类型及返回的类型,便可以很好的利用XMPP来进行数据通讯
 
XMPP官方网站——http://xmpp.org
 
 
 
 
 
 
===============================================================
===============================================================
一、即时通讯软件 XMPP
 
二、服务器搭建——安装MySQL
1.安装 MySQL
2.启动MySQL服务器
3.设置MySQL命令行搜索路径
打开终端,输入:
sudo vi ~/.bash_profile
输入 i
然后粘贴以下内容
# mysql
alias mysql='/usr/local/mysql/bin/mysql'
alias mysqladmin='/usr/local/mysql/bin/mysqladmin'
# ls
alias ls='ls -G'
按ESC键
输入 :wq
重新启动终端程序
 
4.修改MySQL的管理员密码
mysqladmin -u root password "123456"
 
5.删除 MySQL 方法
1>先停止所有mysql有关进程
2>sudo rm /usr/local/mysql
3>sudo rm -rf /usr/local/mysql*
4>sudo rm -rf /Library/StartupItems/MySQLCOM
5>sudo rm -rf /Library/PreferencePanes/My*
6>sudo vi /etc/hostconfig # removed the line MYSQLCOM=-YES-
7>rm -rf ~/Library/PreferencePanes/My*
8>sudo rm -rf /Library/Receipts/mysql*
9>sudo rm -rf /Library/Receipts/MySQL*
10>sudo rm -rf /var/db/receipts/com.mysql.*
 
三、服务器搭建——Openfire
      可用服务器地址:http://xmpp.org/xmpp-software/servers/
1.Openfire简介
采用Java开发,开源的实时协作(RTC)服务器,基于XMPP(Jabber)协议
安装Openfire之前,需要确认是否安装了JDK
如果没有,需要安装jdk-7u45-macosx-x64
可以轻易的构建高效率的即时通信服务器
安装和使用简单,并利用Web进行管理
单台服务器可支持上万(1000)并发用户
 
安装位置:/usr/local/openfire/
安装位置该文件夹的用户访问权限
数据库脚本保存在/usr/local/openfire/resources/database文件夹下

3.修改/usr/local/openfire/目录权限

4.设置openfire数据库

1>将 /usr/local/openfire/resources/database/openfire_mysql.sql 复制到桌面
2>在MySQLWorkbench,导入该文件并执行
 
3>执行角本文件
 
5.Openfire设置
1>在系统偏好中确保Openfire服务已经启动
2>使用浏览器访问:http://localhost:9090
3>如果需要重新配置,可以修改/usr/local/openfire/conf/openfire.xml,将末尾的<setup>true</setup>修改为<setup>false</setup>
4>即可:重新设置Openfire不会影响已经设置好的用户信息,只是在忘记管理员密码是重新设置即可。
 
6.设置服务器(注意域名)
 
 
7.设置数据库
 
四、iOS的XMPP框架——XMPPFramework
 
其他语言可用框架地址:http://xmpp.org/xmpp-software/libraries/
课程选用:XMPPFramework,唯一可用的OC框架
 
1.导入XMPPFramework框架(1)
下载XMPPFramework框架:
 
git clone
导入依赖框架
CocoaLumberjack:日志框架
CocoaAsyncSocket:底层网络框架,实现异步Socket网络通讯
                             需要添加CFNetwork&Security框架依赖
KissXML:XML解析框架
             需要添加libxml2.dylib框架依赖
             需要指定如下编译选项:
             Other Linker Flags = -lxml2
             Header Search Paths = /usr/include/libxml2
libidn:
 
1>设置XML头文件搜索路径
2>设置其他链接标记
 
2.导入XMPPFramework框架(2)
将以下4个文件夹导入到项目
Authentication
Categories
Core
Utilities
另外还需要添加libresolv.dylib依赖
 
3.导入XMPPFramework框架(3)
导入XMPP扩展框架
Extensions
 
将Sample_XMPPFramework.h添加到项目,并且重命名为XMPPFramework.h
 
在终端输入:
git commit -m “添加XMPP框架”
可以一次性提交所有增加的文件
 
4.XMPP框架常用扩展
XEP-0045: 多用户聊天
XEP-0060: 发布-订阅
XEP-0065: SOCKS5字节流
XEP-0085: 聊天状态通知
XEP-0096: 文件传输
XEP-0172: 用户昵称
XEP-0184: 消息送达
CoreDataStorage: 数据存储
Reconnect:重新连接
Roster:花名册
 
 
5.XMPP核心文件
XMPPStream:是开发过程中最主要交互的类,所有扩展和自定义代码均要基于此类进行
XMPPParser:供XMPPStream解析使用
XMPPJID:提供了一个不可变JID的实现,遵守NSCopying协议和NSCoding协议
XMPPElement:以下三个XMPP元素的基类
XMPPIQ  :请求
XMPPMessage  :消息
XMPPPresence  :出席
XMPPModule:开发XMPP扩展时使用
XMPPLogging:XMPP的日志框架
XMPPInternal:整个XMPP框架内部使用的核心和高级底层内容
 
6.XMPPStream实例的配置
1>配置如何连接至XMPP服务器
2>添加代理
3>添加模块
4>开始连接
5>开始授权
 
注意:
XMPP框架仅提供了一个最小的代理委托系统用于接收三种XMPP类型(IQ、Message和Presence),如果要实现更多的功能,开发者还需要编写大量的相关代码
为了简化开发,通常将XMPPStream放置在AppDelegate中,以便于全局访问

7.XMPP框架提供的主要扩展功能

XMPPReconnect:如果意外中断,自动重连XMPP流
XMPPRoster:标准的XMPP花名册
XMPPRoom:提供多人聊天支持
XMPPPubSub:提供公共订阅支持
……
 
8.通信类别及公共XML属性
使用XMPP的实时消息传递系统包含三大通信类别:
消息传递,其中数据在有关各方之间传输
联机状态,允许用户广播其在线状态和可用性
信息/查询请求,它允许XMPP实体发起请求并从另一个实体接收响应
 
以上三种类型的XMPP节都拥有以下公共属性:
from:源XMPP实体的JID
to:目标接收者的JID
id:当前对话的可选标识符
type:节的可选子类型
xml:lang:如果内容是人们可读的,则为消息语言的描述
 
 

五、用户登录的流程图

1.用户登录的步骤

XMPPFrame框架是通过代理的方式实现消息传递的

实现用户登录的步骤如下:
1>实例化XMPPStream并设置代理,同时添加代理到工作队列
2>使用JID连接至服务器,默认端口为5222,JID字符串中需要包含服务器的域名
3>在完成连接的代理方法中验证用户密码,连接完成后XMPPStream的isConnect属性为YES
4>在验证代理方法中判断用户是否登录成功
5>上线或者下线成功后,向服务器发送Presence数据,以更新用户在服务器的状态
 
2.AppDelegate.h
为了简化开发,XMPP的引用程序通常会将XMPPStream放置在AppDelegate中,以便于全局访问
 
在AppDelegate中添加以下属性和方法定义
 
@property (strong, nonatomic, readonly) XMPPStream *xmppStream;
- (void)connect;
- (void)disconnect;
 
3.XMPPStream私有方法——设置代理及通知状态

//设置XMPPStream

- (void)setupStream {

    _xmppStream = [[XMPPStream alloc] init];

    [_xmppStream addDelegate:self delegateQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)];

}

// XMPPStream上线

- (void)goOnline {

    XMPPPresence *presence = [XMPPPresence presence];

    [_xmppStream sendElement:presence];

}

// XMPPStream离线

- (void)goOffline {

    XMPPPresence *presence = [XMPPPresence presenceWithType:@"unavailable"];

    [_xmppStream sendElement:presence];

}

4.connect方法

- (void)connect {

    // 1. 设置XMPPStream

    [self setupStream];

    // 2. 设置用户名、密码及服务器

    // 3. 设置XMPPStream信息

     [_xmppStream setMyJID:[XMPPJID jidWithString:userName]];

    [_xmppStream setHostName:server];

     _myPassword = password;

    // 4. 连接至服务器,如果没有指定jid和hostName,连接才会报错

       NSError *error = nil;

    [_xmppStream connectWithTimeout:XMPPStreamTimeoutNone error:&error];

    if (error) {

        NSLog(@"连接错误:%@", error.localizedDescription);

    }

}

5.disconnect方法

- (void)disconnect

{

    // 1. 发送离线状态

    [self goOffline];

    // 2. XMPPStream断开连接

    [_xmppStream disconnect];

}

6.XMPP代理方法

#pragma mark - XMPPStream代理方法

#pragma mark 连接到服务器

- (void)xmppStreamDidConnect:(XMPPStream *)sender

{

    // 1. 验证密码

      NSError *error = nil;

    [_xmppStream authenticateWithPassword:_myPassword error:&error];

    if (error) {

        NSLog(@"身份验证错误:%@", error.localizedDescription);

    }

}

#pragma mark 通过验证

- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender

{

    [self goOnline];

}

#pragma mark 验证失败

- (void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(DDXMLElement *)error

{

    NSLog(@"验证失败:%@", error);

}

7.在应用程序状态切换时连接或断开连接

#pragma mark 应用程序注销激活状态

- (void)applicationWillResignActive:(UIApplication *)application

{

    // 断开连接

    [self disconnect];

}

#pragma mark 应用程序重新被激活

- (void)applicationDidBecomeActive:(UIApplication *)application

{

    // 连接

    [self connect];

}

8.在AppDelegate中添加访问助手方法

#pragma mark - AppDelegate访问助手方法

/**

 AppDelegate的访问助手

 */

- (AppDelegate *)appDelegte

{

    return (AppDelegate *)[[UIApplication sharedApplication] delegate];

}

/**

 AppDelegate的XMPPStream属性访问助手

 */

- (XMPPStream *)xmppStream

{

    return [[self appDelegte] xmppStream];

}

 
原文地址:https://www.cnblogs.com/oc-bowen/p/5263428.html