XMPP登录的原理如下:客户端先发送一个用户名连接服务器,连接成功后 服务器会执行相应的回调方法通知客户端,客户端在连接成功后再发送密码进行授权登录。
XMPP用户登录的步骤:(如下图所示:)
XMPPFrame框架是通过代理的方式实现消息传递的
实现用户登录的步骤如下:
1. 实例化XMPPStream并设置代理,同时添加代理到工作队列
2. 使用JID连接至服务器,默认端口为5222,JID字符串中需要包含服务器的域名
3. 在完成连接的代理方法中验证用户密码,连接完成后XMPPStream的isConnect属性为YES
4. 在验证代理方法中判断用户是否登录成功
5. 上线或者下线成功后,向服务器发送Presence数据,以更新用户在服务器的状态
重点使用的是Core下的类,如下图:
XMPP几个核心类的介绍:
XMPPStream:是开发过程中最主要交互的类,所有扩展和自定义代码均要基于此类进行
XMPPParser:供XMPPStream解析使用
XMPPJID:提供了一个不可变JID的实现,遵守NSCopying协议和NSCoding协议
XMPPElement:以下三个XMPP元素的基类
XMPPIQ :请求(加好友)
XMPPMessage :消息
XMPPPresence :出席(标示用户的在线状态)
XMPPModule:开发XMPP扩展时使用
XMPPLogging:XMPP的日志框架
XMPPInternal:整个XMPP框架内部使用的核心和高级底层内容
新建工程,实现XMPP的登录程序:
AppDelegate.h
// // AppDelegate.h // 02.XMPP框架的导入 // // Created by apple on 14/12/6. // Copyright (c) 2014年 heima. All rights reserved. // #import <UIKit/UIKit.h> @interface AppDelegate : UIResponder <UIApplicationDelegate> @property (strong, nonatomic) UIWindow *window; -(void)logout; // 注销 @endAppDelegate.m
// // AppDelegate.m // 02.XMPP框架的导入 // // Created by apple on 14/12/6. // Copyright (c) 2014年 heima. All rights reserved. // #import "AppDelegate.h" #import "XMPPFramework.h" /** 在AppDelegate中实现登录 1. 初始化XMPPStream。 2. 连接到服务器(传一个JID)。 3. 连接到服务器成功后,再发送密码(授权)。 4. 登录成功后,发送在线消息。 (当你登录成功时,需要发送一个在线的消息给其它好友,告诉别人你在线。如果你登录之后不发送在线消息,Openfire服务器中"你"的头像仍然是绿的) */ @interface AppDelegate ()<XMPPStreamDelegate>{ XMPPStream *_xmppStream; } // 1. 初始化XMPPStream -(void)setupXMPPStream; // 2. 连接到服务器 -(void)connectToHost; // 3. 连接到服务器成功后,再发送密码到服务器(授权) -(void)sendPwdToHost; // 4. 授权成功后,再发送"在线"消息 -(void)sendOnlineToHost; @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // 程序一启动就连接到主机 [self connectToHost]; return YES; } #pragma mark 私有方法 #pragma mark 初始化XMPPStream -(void)setupXMPPStream { _xmppStream = [[XMPPStream alloc] init]; // 设置代理 [_xmppStream addDelegate:self delegateQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)]; } #pragma mark 连接到主机 -(void)connectToHost { NSLog(@"开始连接到服务器"); if (!_xmppStream) { [self setupXMPPStream]; } // 设置登录用户的JID // resource 标示用户登录的客户端 iPhone android widowphone XMPPJID *myJID = [XMPPJID jidWithUser:@"lisi" domain:@"localhost" resource:@"iphone"]; _xmppStream.myJID = myJID; // 设置服务器的域名 _xmppStream.hostName = @"localhost"; // 不仅可以是域名还可以是IP地址 // 设置端口——其实可以不用设置,因为默认的端口就是5222 _xmppStream.hostPort = 5222; // 连接 NSError *error = nil; [_xmppStream connectWithTimeout:XMPPStreamTimeoutNone error:&error]; if (error) { NSLog(@"%@", error); } } #pragma mark 与主机连接成功后,调用此方法发送密码进行授权登录 -(void)sendPwdToHost { NSLog(@"开始发送密码进行授权"); NSError *error = nil; [_xmppStream authenticateWithPassword:@"123456" error:&error]; if (error) { NSLog(@"%@", error); } } #pragma mark 授权成功后,发送在线消息 -(void)sendOnlineToHost { NSLog(@"发送在线消息"); XMPPPresence *presence = [XMPPPresence presence]; NSLog(@"%@", presence); [_xmppStream sendElement:presence]; } #pragma mark - XMPPStream 的代理方法 #pragma mark 与主机连接成功 -(void)xmppStreamDidConnect:(XMPPStream *)sender { NSLog(@"与主机连接成功"); // 主机连接成功后, 发送密码进行授权 [self sendPwdToHost]; } #pragma mark 与主机断开连接 -(void)xmppStreamDidDisconnect:(XMPPStream *)sender withError:(NSError *)error { // 如果有错误,代表连接失败 NSLog(@"与主机断开连接 %@", error); } #pragma mark 授权成功 -(void)xmppStreamDidAuthenticate:(XMPPStream *)sender { NSLog(@"授权成功"); // 授权成功后,发送在线消息 [self sendOnlineToHost]; } #pragma mark 授权失败 -(void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(DDXMLElement *)error { NSLog(@"授权失败 %@", error); } #pragma mark 公共方法 -(void)logout { // 注销步骤: 发送离线消息 再断开连接 // 1. 发送离线消息 XMPPPresence *offline = [XMPPPresence presenceWithType:@"unavailable"]; [_xmppStream sendElement:offline]; // 2. 与服务器断开连接 [_xmppStream disconnect]; } @endviewController.m
// // ViewController.m // 02.XMPP框架的导入 // // Created by apple on 14/12/6. // Copyright (c) 2014年 heima. All rights reserved. // #import "ViewController.h" #import "AppDelegate.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { // 注销 AppDelegate *app = [UIApplication sharedApplication].delegate; [app logout]; } @end运行结果如下:
发现服务器端的李四头像变亮。
点击屏幕,注销账户,如下:
刷新后发现lisi头像变暗。
此程序完全参考XMPP框架内Xcode中实现登录的Demo (XMPPiPhone工程)