1.XMPPStream通讯示意图
2 XMPPStream的使用
- 由于XMPPStream是基于myJID建立的长连接,因此在应用程序中应该仅被实例化一次(didFinishLaunchingWithOptions)
- 如果程序视图多次实例化XMPPStream,应该终止程序运行,以提示程序员纠错
- XMPPStream除了负责设定应用程序的代理之外,还用于添加XMPP框架的扩展,例如电子名片、花名册、自动连接等
- 当出现内存警告时,应用程序内部属性会被销毁,此时,应该在dealloc方法中,销毁并释放XMPPStream对象以及相关的扩展
-
"Error Domain=XMPPStreamErrorDomain Code=1 "Attempting to connectwhile already connected or connecting." UserInfo=0x7fb73167a500 {NSLocalizedDescription=Attempting to connect while already connected or connecting.}
再次登录过程中,如果出现以上的错误,说明已经存在一个与服务器的连接
/* 用户登录流程
1.初始化XMPPStream
2.连接服务器(传一个jid)
3.连接成功,接着发送密码
// 默认登录成功是不在线的
4.发送一个 "在线消息"给服务器 ->可以通知其它用户你上线
*/
@interface AppDelegate ()<XMPPStreamDelegate>{
XMPPStream *_xmppStream;//与服务器交互的核心类
XMPPResultBlock _resultBlock;//结果回调Block
}
/**
* 1.初始化XMPPStream
*/
-(void)setupStream;
/**
* 2.连接服务器(传一个jid)
*/
-(void)connectToHost;
/**
* 3.连接成功,接着发送密码
*/
-(void)sendPwdToHost;
/**
* 4.发送一个 "在线消息"给服务器
*/
-(void)sendOnline;
/**
* 发送 “离线”消息
*/
-(void)sendOffline;
/**
* 与服务器断开连接
*/
-(void)disconncetFromHost;
@end
相应的方法实现
#pragma mark -私有方法
-(void)setupStream{
// 方法被调用时,要求_xmppStream必须为nil,否则通过断言提示程序员,并终止程序运行!
NSAssert(_xmppStream ==nil,@"视图多次实例化XMPPStream!");
// 创建XMPPStream对象
_xmppStream = [[XMPPStreamalloc]init];
//设置代理
//由于所有网络请求都是做基于网络的数据处理,这些数据处理工作与界面UI无关。
//因此可以让代理方法在其他线城中运行,从而提高程序的运行性能,避免出现应用程序阻塞的情况
[_xmppStream addDelegate:selfdelegateQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0)];
// 后台支持
#if !TARGET_IPHONE_SIMULATOR
[_xmppStream setEnableBackgroundingOnSocket:YES];
#endif
}
-(void)connectToHost{
// 1.设置登录用户的jid
// resource 用户登录客户端设备登录的类型
XMPPJID *myJid = [XMPPJIDjidWithUser:@"zhangsan"domain:@"liangliang.local"resource:@"iphone"];
_xmppStream.myJID = myJid;
// 2.设置主机地址
_xmppStream.hostName =@"127.0.0.1";
// 3.设置主机端口号 (默认就是5222,可以不用设置)
_xmppStream.hostPort =5222;
// 4.发起连接
NSError *error = nil;
// 缺少必要的参数时就会发起连接失败 ?没有设置jid
[_xmppStream connectWithTimeout:XMPPStreamTimeoutNoneerror:&error];
if (error) {
NSLog(@"%@",error);
}else{
NSLog(@"发起连接成功");
}
}
-(void)sendPwdToHost{
NSError *error = nil;
[_xmppStream authenticateWithPassword:@"xxxx"error:&error];
if (error) {
NSLog(@"%@",error);
}
}
-(void)sendOnline{
//XMPP框架,已经把所有的指令封闭成对象
XMPPPresence *presence = [XMPPPresencepresence];
NSLog(@"%@",presence);
[_xmppStream sendElement:presence];
}
-(void)sendOffline{
XMPPPresence *offline = [XMPPPresencepresenceWithType:@"unavailable"];
[_xmppStream sendElement:offline];
}
4.XMPP登录、注册示意图
#pragma mark -XMPPStream的代理
#pragma mark 连接建立成功
-(void)xmppStreamDidConnect:(XMPPStream *)sender{
NSLog(@"%s",__func__);
[selfsendPwdToHost];
}
#pragma mark 登录成功
-(void)xmppStreamDidAuthenticate:(XMPPStream *)sender{
NSLog(@"%s",__func__);
[selfsendOnline];
//回调resultBlock
//主要是方便切换登陆LoginControl和主界面MainControl的控制器切换
if (_resultBlock) {
_resultBlock(XMPPResultTypeLoginSucess);
}
}
#pragma mark 登录失败
-(void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(DDXMLElement *)error{
NSLog(@"%s %@",__func__,error);
//回调resultBlock
if (_resultBlock) {
_resultBlock(XMPPResultTypeLoginFailure);
}
}
#pragma mark -控制器的公共方法
#pragma mark 用户登录
-(void)xmppLogin:(XMPPResultBlock)resultBlock{
// 保存resultBlock
_resultBlock = resultBlock;
// 连接服务器开始登录的操作
[self connectToHost];
}
#pragma mark 用户注销
-(void)xmppLogout{
// 1.发送 "离线消息"给服务器
[selfsendOffline];
// 2.断开与服务器的连接
[selfdisconncetFromHost];
}
-(void)disconncetFromHost{
[_xmppStream disconnect];
}