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; // 注销
@end
AppDelegate.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];
}
@end
viewController.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工程)