UI进阶 即时通讯之XMPP登录、注册

一、即时通讯

  • 什么是即时通讯、

    • 即时通讯(Instant Messaging)是目前Internet上最为流行的通讯方式,各种各样的即时通讯软件也层出不穷,服务提供商也提供了越来越丰富的通讯服务功能。
  • 即时通讯的实现方式
    • 即时通讯有多种实现方式,例如:XMPP、环信、融云等。
  • 什么是XMPP
    • XMPP(XML,Messages,Presence,Protocol)是基于可扩展标记语言(XML)的协议,可用于即时通信(IM)。
      ——可扩展消息处理现场协议
  • XMPP优点
    • 开放
      XMPP协议是由JSF开源社区组织开发的,不属于任何的机构和个人,从根本上保证了其开放性。
    • 2. 标准
       互联网工程工作组将XMPP于2002年正式列为认可的实时通讯及Presence技术。
    • 3.分布式的网络架构
      XMPP 协议虽然是基于Client/Server 架构,但是XMPP协议本身并没有这样的限制。网络的架构和电子邮件十分相似,但没有结合任何特定的网络架构,适用范围非常广泛。 
    • XMPP 协议具有良好的扩展性
      基于XML 建立起来的应用具有良好的语义完整性和扩展性。
    • XMPP 具有很好的弹性
      XMPP 除了可用在即时通信的应用程序,还能用在网络管理、内容供稿、协同工具、档案共享、游戏、远端系统监控等。
    • 安全性
      XMPP在Client-to-Server通信和Server-to-Server通信中都使用TLS (Transport Layer Security)协议作为通信通道的加密方法,保证通信的安全。

二、XMPP实现即时通讯

  • 原理
    实现即时通讯至少需要一个服务器端、两个客户端。
  • 下面我们准备需要的环境:
    1、XMPP服务器     2、XMPP客户端(辅助调试)

1、XMPP环境搭建

http://www.cnblogs.com/fearlessyyp/p/5506644.html

第一次打开可能会有点儿慢,图片很多,步骤很详细,祝搭建成功。

2、工程中添加XMPP

1、创建新工程
2、导入XMPP框架
3、引入XMPP需要的依赖库 libxml   libresolv
4、设置路径:在工程的"Build Settings"页中找到"Header Search Path"项,添加"/usr/include/libxml2"。在"Other Linker Flags"项,添加"-lxml2"  XML解析适配

三、XMPP实现登录、注册

  1、Main.storyboard搭建界面

  2、初始化XMPP通道

  XMPPFramework框架中有一个XMPPConfig.h文件,里面宏定义了连接服务器用到的参数,可对照着自己的服务器参数修改宏

 1 //
 2 //  XMPPConfig.h
 3 //  XMPPSample
 4 //
 5 //  Created by lewis on 14-3-27.
 6 //  Copyright (c) 2014年 com.lanou3g. All rights reserved.
 7 //
 8
 9 #ifndef XMPPSample_XMPPConfig_h
10 #define XMPPSample_XMPPConfig_h
11
12 //openfire服务器IP地址
13 #define  kHostName      @"127.0.0.1"
14 //openfire服务器端口 默认5222
15 #define  kHostPort      5222
16 //openfire域名
17 #define kDomin @"127.0.0.1"
18 //resource
19 #define kResource @"iOS"
20 #endif

  初始化通道里用到的kHostName、kHostPort都是在XMPPConfig.h文件中定义的

1         //初始化通道
2         self.xmppStream = [[XMPPStream alloc] init];
3         //openfire服务器IP地址
4         self.xmppStream.hostName = kHostName;
5         //openfire服务器端口 默认5222
6         self.xmppStream.hostPort = kHostPort;
7         //添加代理
8         [self.xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()
9          ];

  3、主要实现

  XMPPStream关键方法

  登录用到的方法

  注册用到的方法

  封装了一个XMPPManager类

  XMPPManager.h  

 1 #import <Foundation/Foundation.h>
 2 #import "XMPPFramework.h"
 3
 4 @interface XMPPManager : NSObject
 5 /// 声明一个通道属性
 6 @property (nonatomic, strong)XMPPStream *xmppStream;
 7
 8 #pragma mark - 单例
 9 + (instancetype)sharedXMPPManager;
10
11 #pragma mark - 登录
12 - (void)loginWithUserName:(NSString *)userName
13                  password:(NSString *)password;
14
15 #pragma mark - 注册
16 - (void)registerWithUserName:(NSString *)userName
17                     password:(NSString *)password;
18 @end

  XMPPManager.m

  1 #import "XMPPManager.h"
  2
  3 static XMPPManager *xmppManager = nil;
  4
  5 // 定义枚举值,用来区分当前的状态是登录还是注册
  6 typedef NS_ENUM(NSUInteger, ConnectToServerPurpose) {
  7     ConnectToServerPurposeLogin,  // 登录
  8     ConnectToServerPurposeRegister,  // 注册
  9 };
 10
 11 @interface XMPPManager ()<XMPPStreamDelegate>
 12 /// 用户名
 13 @property (nonatomic, copy) NSString *userName;
 14 /// 密码
 15 @property (nonatomic, copy) NSString *password;
 16
 17 /// 记录当前的状态是登录还是注册
 18 @property (nonatomic) ConnectToServerPurpose connectToServer;
 19 @end
 20
 21 @implementation XMPPManager
 22 #pragma mark - 单例
 23 + (instancetype)sharedXMPPManager {
 24     static dispatch_once_t oneToken;
 25     dispatch_once(&oneToken, ^{
 26         xmppManager = [[XMPPManager alloc] init];
 27     });
 28     return xmppManager;
 29 }
 30
 31 #pragma mark - 创建通道
 32 - (instancetype)init {
 33     if (self = [super init]) {
 34         // 初始化通道对象
 35         self.xmppStream = [[XMPPStream alloc] init];
 36         // 设置Openfire服务器主机名
 37         self.xmppStream.hostName = kHostName;
 38         // 设置服务器端口号
 39         self.xmppStream.hostPort = kHostPort;
 40         // 设置代理
 41         [self.xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];
 42     }
 43     return self;
 44 }
 45
 46 #pragma mark - 登录
 47 - (void)loginWithUserName:(NSString *)userName
 48                  password:(NSString *)password {
 49     self.userName = userName;
 50     self.password = password;
 51     // 设置当前的状态为登录
 52     self.connectToServer = ConnectToServerPurposeLogin;
 53     // 连接服务器
 54     [self linkServer];
 55
 56 }
 57
 58 #pragma mark - 注册
 59 - (void)registerWithUserName:(NSString *)userName
 60                     password:(NSString *)password {
 61     self.userName = userName;
 62     self.password = password;
 63     // 设置当前的状态为注册
 64     self.connectToServer = ConnectToServerPurposeRegister;
 65     // 连接服务器
 66     [self linkServer];
 67 }
 68
 69 #pragma mark - 连接服务器
 70 - (void)linkServer {
 71     // 要连接服务器,要有用户身份认证
 72     // 身份认证
 73     // 参数1:用户名
 74     // 参数2:domain是域名
 75     // 参数3:资源
 76     XMPPJID *jid = [XMPPJID jidWithUser:self.userName domain:kDomin resource:kResource];
 77
 78     // 通过通道进行身份验证
 79     self.xmppStream.myJID = jid;
 80
 81     // (根据项目需求来定)如果当前聊天工具处于连接状态,或者已经连接了,此时你需要去切断连接
 82     if ([self.xmppStream isConnected] || [self.xmppStream isConnecting]) {
 83         // 调用自定义方法
 84         [self disconnectionToServer];
 85     }
 86
 87     // 连接超时
 88     NSError *error = nil;
 89     [self.xmppStream connectWithTimeout:30 error:&error];
 90     if (error) {
 91         NSLog(@"服务器连接超时");
 92     }
 93 }
 94
 95 #pragma mark - 手动断开连接(自定义方法)
 96 - (void)disconnectionToServer {
 97     // 设置当前用户状态为下线
 98     XMPPPresence *presence = [XMPPPresence presenceWithType:@"unavailable"];
 99     // 告诉通道下线
100     [self.xmppStream sendElement:presence];
101     // 通道失去连接
102     [self.xmppStream disconnect];
103     NSLog(@"(自定义方法)断开连接");
104 }
105
106
107 #pragma mark -----------------以下XMPPStreamDelegate是协议中的方法----------------
108
109 #pragma mark - 连接成功
110 - (void)xmppStreamDidConnect:(XMPPStream *)sender {
111     NSLog(@"服务器连接成功");
112     // 校验密码
113     switch (self.connectToServer) {
114         case ConnectToServerPurposeLogin:
115             // 校验登录密码
116             [self.xmppStream authenticateWithPassword:self.password error:nil];
117             break;
118         case ConnectToServerPurposeRegister:
119             // 注册
120             [self.xmppStream registerWithPassword:self.password error:nil];
121             break;
122         default:
123             break;
124     }
125
126 }
127
128 #pragma mark - 连接超时
129 - (void)xmppStreamConnectDidTimeout:(XMPPStream *)sender {
130     NSLog(@"服务器连接超时");
131 }
132
133 #pragma mark - 已经断开连接
134 - (void)xmppStreamDidDisconnect:(XMPPStream *)sender withError:(NSError *)error {
135     // 连接被断开的情况
136     // 1、自己手动断开
137     // 2、被动断开
138     NSLog(@"已经断开连接");
139 }
140
141 #pragma mark - 用户认证失败
142 - (void) xmppStream:(XMPPStream *)sender didNotAuthenticate:(DDXMLElement *)error {
143     NSLog(@"登录失败 %@", error);
144 }
145
146 #pragma mark - 认证成功
147 - (void)xmppStreamDidAuthenticate:(XMPPStream *)sender {
148     // 设置用户状态为上线
149     XMPPPresence *presence = [XMPPPresence presenceWithType:@"available"];
150     // 告诉通道上线
151     [self.xmppStream sendElement:presence];
152     NSLog(@"用户已上线");
153
154 }
155 #pragma mark -----------------以上是XMPPStreamDelegate协议中的方法----------------
156 // 关于注册是否成功的代理方法写在了RegisterViewController.m中
157
158
159 @end

LoginViewController.m

 1 #import "LoginViewController.h"
 2 #import "XMPPManager.h"
 3
 4 @interface LoginViewController ()
 5 /// 用户名
 6 @property (weak, nonatomic) IBOutlet UITextField *userNameTextField;
 7 /// 密码
 8 @property (weak, nonatomic) IBOutlet UITextField *passwordTextField;
 9
10 @end
11
12 @implementation LoginViewController
13
14 - (void)viewDidLoad {
15     [super viewDidLoad];
16
17
18 }
19 #pragma mark - 登录按钮的响应方法
20 - (IBAction)loginAction:(UIButton *)sender {
21     // 调用登录方法
22     [[XMPPManager sharedXMPPManager] loginWithUserName:self.userNameTextField.text password:self.passwordTextField.text];
23 }
24
25 @end

RegisterViewController.m

 1 #import "RegisterViewController.h"
 2 #import "XMPPManager.h"
 3
 4 @interface RegisterViewController ()<XMPPStreamDelegate>
 5 /// 用户名
 6 @property (weak, nonatomic) IBOutlet UITextField *userNameTextField;
 7 /// 密码
 8 @property (weak, nonatomic) IBOutlet UITextField *passwordTextField;
 9
10 @end
11
12 @implementation RegisterViewController
13
14 - (void)viewDidLoad {
15     [super viewDidLoad];
16
17 }
18 #pragma mark - 注册按钮点击事件
19 - (IBAction)registerAction:(UIButton *)sender {
20     XMPPManager *manager = [XMPPManager sharedXMPPManager];
21     // 设置代理
22     [manager.xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];
23     // 调用注册方法
24     [manager registerWithUserName:self.userNameTextField.text password:self.passwordTextField.text];
25
26
27 }
28 #pragma mark -----------------以下是XMPPStreamDelegate协议中的方法----------------
29 #pragma mark - 注册成功, 返回登录界面
30 - (void)xmppStreamDidRegister:(XMPPStream *)sender {
31     NSLog(@"注册成功");
32     [self dismissViewControllerAnimated:YES completion:nil];
33 }
34
35 #pragma mark - 注册失败
36 - (void)xmppStream:(XMPPStream *)sender didNotRegister:(DDXMLElement *)error {
37     NSLog(@"注册失败 error = %@", error);
38 }
39
40 #pragma mark -----------------以上是XMPPStreamDelegate协议中的方法----------------
41 @end

这个Openfire的界面可以查看数据库中的用户

时间: 2024-08-02 07:02:04

UI进阶 即时通讯之XMPP登录、注册的相关文章

UI进阶 即时通讯之XMPP好友列表、添加好友、获取会话内容、简单聊天

这篇博客的代码是直接在上篇博客的基础上增加的,先给出部分代码,最后会给出能实现简单功能的完整代码. UI进阶 即时通讯之XMPP登录.注册 1.好友列表 初始化好友花名册 1 #pragma mark - 管理好友 2 // 获取管理好友的单例对象 3 XMPPRosterCoreDataStorage *rosterStorage = [XMPPRosterCoreDataStorage sharedInstance]; 4 // 用管理好友的单例对象初始化Roster花名册 5 // 好友操

UI进阶 即时通讯之XMPP环境搭建

搭建XMPP环境需要几个辅助工具 1.XAMPP     XAMPP(Apache+MySQL+PHP+PERL)是一个功能强大的建 XAMPP 软件站集成软件包.     许多人通过他们自己的经验认识到安装 Apache 服务器是件不容易的事儿.如果您想添加 MySQL.PHP 和 Perl,那就更难了.XAMPP 是一个易于安装且包含 MySQL.PHP 和 Perl 的 Apache 发行版.XAMPP 的确非常容易安装和使用:只需下载,解压缩,启动即可.2.Openfire      O

UI进阶 即时通讯之卸载Openfire

首先,确保你已经关掉了openfire打开终端 (在应用程序-->实用工具-->)输入以下命令sudo rm -rf /Library/PreferencePanes/Openfire.prefPane sudo rm -rf /usr/local/openfire sudo rm -rf /Library/LaunchDaemons/org.jivesoftware.openfire.plist 第一条会让你输入管理员密码,尽管你输入的时候,终端不会显示,不必担心,正确输入后按回车,它就执行

XMPP登录注册好友群组_实战教学1

1. 环境准备:openfire + mysql 5.1.6 + Xcode5 + XMPP.Framework (至于环境的配置, 请自己百度, 推荐: http://www.cnblogs.com/xiaodao/archive/2013/04/05/3000554.html) 2. cocoapods 1 platform :ios, '7.0' 2 pod "XMPPFramework", "~>3.6.4" 3.工程: ARC + COREDATA

即时通讯之XMPP好友列表、添加好友、获取会话内容、简单聊天

1.好友列表 初始化好友花名册 1 #pragma mark - 管理好友 2 // 获取管理好友的单例对象 3 XMPPRosterCoreDataStorage *rosterStorage = [XMPPRosterCoreDataStorage sharedInstance]; 4 // 用管理好友的单例对象初始化Roster花名册 5 // 好友操作是耗时操作 6 self.xmppRoster = [[XMPPRoster alloc] initWithRosterStorage:r

XMPP登录注册好友群组_实战教学2

Message: 接着写 .h 1 /*! 2 * @Author Dylan. 3 * 4 * callback Block 5 */ 6 typedef void(^sendSuccess)(); 7 typedef void(^sendFailure)(id); 8 9 /*! 10 * sendMessageBy model 11 */ 12 - (void)sendMessage: (ADMessageModel *)message 13 sendSuccess: (sendSucce

XMPP登录注册好友群组_实战教学3

// Roster 我们继续写 获取好友列表 .h 1 /*! 2 * @Author Dylan. 3 * 4 * Roster 5 */ 6 7 typedef void (^refreshRosterListFailure) (id); 8 typedef void (^Rosterlist) (id); 9 10 /*! 11 * @Author Dylan. 12 * 13 * request for roster list. IQ 14 */ 15 - (void)refreshRo

xmpp登录注册好友群组_实战教学4

// 实现好友状态的获取 - 在线.离线  别的状态自己去写一下判断和回掉就好 .h 1 /*! 2 * @Author Dylan. 3 * 4 * Paresence 5 */ 6 typedef void (^userGoOnline) (NSString *); 7 typedef void (^userGoOffline) (NSString *); 8 9 - (void)refreshRosterPresence: (userGoOnline)online 10 offline:

xmpp即时通讯协议的特性---长处和缺点!

xmpp协议的定义? XMPP是一种基于标准通用标记语言的子集XML的协议,它继承了在XML环境中灵活的发展性. 因此.基于XMPP的应用具有超强的可扩展性.经过扩展以后的XMPP能够通过发送扩展的信息来处理用户的需求.以及在XMPP的顶端建立如内容公布系统和基于地址的服务等应用程 序. 并且,XMPP包括了针对server端的软件协议,使之能与还有一个进行通话,这使得开发人员更easy建立客户应用程序或给一个配好系统加入功能. 在此我概括一下xmpp协议的优缺点: 长处: XMPP协议是自由.