您的位置:首页 > 移动开发 > IOS开发

IOS -- XMPPFramework 即时聊天(3:XMPPFramework 实现连接服务器)

2015-04-24 10:42 645 查看
1.首先我来认识这些对象名词的含义。

XMPPStream:xmpp基础服务类

XMPPRoster:好友列表类

XMPPRosterCoreDataStorage:好友列表(用户账号)在core data中的操作类

XMPPvCardCoreDataStorage:好友名片(昵称,签名,性别,年龄等信息)在core data中的操作类

XMPPvCardTemp:好友名片实体类,从数据库里取出来的都是它

xmppvCardAvatarModule:好友头像

XMPPReconnect:如果失去连接,自动重连

XMPPRoom:提供多用户聊天支持

XMPPPubSub:发布订阅

2.开始实现 (在XMPPService.m中)

static XMPPService *sharedService;
+ (XMPPService *)sharedInstance{

static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedService = [[XMPPService alloc]init];

[sharedService setupStream];
});
return sharedService;
}


上面是实现一个XMPPService单例,下面是 [sharedService setupStream] 的方法实现

- (void)setupStream{
xmppStream = [[XMPPStream alloc]init];
[xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];

xmppReconnect = [[XMPPReconnect alloc] init];
[xmppReconnect activate:xmppStream];

xmppRosterStorage = [[XMPPRosterCoreDataStorage alloc] init];
xmppRoster = [[XMPPRoster alloc] initWithRosterStorage:xmppRosterStorage];
[xmppRoster activate:xmppStream];
[xmppRoster addDelegate:self delegateQueue:dispatch_get_main_queue()];

[xmppStream setHostName:kXMPPHost];
[xmppStream setHostPort:5222];

if (![self connect]) {
//做连接失败的提示
};
}


a.新建一个XMPPStream对象 并添加delegate方法 [xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];

其中参数delegateQueue 为委托回调所使用的 GCD 队列,dispatch_get_main_queue() 获取主线程 GCD 队列

b.创建XMPPReconnect对象 它实现聊天时断线的重连机制。

c.创建XMPPRoster对象 它为花名册,其实就是好友列表,并添加它的存储策略。

d.设置hostname 和 hostport 其中 kXMPPHost 的形式类似“121.40.xxx.xxx” hostport端口号是可选的,默认是 5222

e.下面是[self connect]的实现

- (BOOL)connect{
if (![xmppStream isDisconnected]) {
return YES;
}

NSString *myJID = [[NSUserDefaults standardUserDefaults] stringForKey:kXMPPmyJID];
NSString *myPassword = [[NSUserDefaults standardUserDefaults] stringForKey:kXMPPmyPassword];

if (myJID == nil || myPassword == nil) {
return NO;
}

[xmppStream setMyJID:[XMPPJID jidWithUser:myJID domain:@"openfire" resource:@"ios"]];
password=myPassword;

NSError *error ;
if (![xmppStream connectWithTimeout:XMPPStreamTimeoutNone error:&error]) {
NSLog(@"my connected error : %@",error.description);
return NO;
}

return YES;
}


a.[xmppStream setMyJID:[XMPPJID jidWithUser:myJID domain:@"openfire" resource:@"ios"]]这里setMyJID是由三部分组成的 :用户名,域名和资源名。列如 test1@openfire/ios

b.[xmppStream
connectWithTimeout:XMPPStreamTimeoutNone error:&error] 使用该方法来进行与服务器连接。

c.一旦连接成功就会走下面xmppstream的代理方法。

#pragma mark - XMPPStreamDelegate
//连接
- (void)xmppStreamWillConnect:(XMPPStream *)sender
{
NSLog(@"xmppStreamWillConnect");
}
- (void)xmppStreamDidConnect:(XMPPStream *)sender
{
NSLog(@"开始连接服务器的时候:xmppStreamDidConnect");
self.isXmppConnected = YES;
if ([[NSUserDefaults standardUserDefaults]objectForKey:kXMPPmyPassword]) {
NSError *error ;
if (![xmppStream authenticateWithPassword:password error:&error]) {
NSLog(@"error authenticate : %@",error.description);
}
}
}


d.一旦连接成功后就会走 xmppStreamDidContent方法,我们在这个方法里进行用户验证。

[xmppStream authenticateWithPassword:password error:&error]这个关键代码 用来进行用户密码验证的。

self.isXmppConnected = YES;是我用来判断是否与服务器连接的变量 你们可以忽略他。

e.在如果验证成功的话 会调用[self goOnlie].如果没成功的话会走 didNotAuthenticate

//验证
- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender
{
NSLog(@"验证成功:xmppStreamDidAuthenticate");
[self goOnline];
}
- (void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(NSXMLElement *)error
{
NSLog(@"验证失败:didNotAuthenticate:%@",error.description);
}

- (NSString *)xmppStream:(XMPPStream *)sender alternativeResourceForConflictingResource:(NSString *)conflictingResource
{
NSLog(@"alternativeResourceForConflictingResource: %@",conflictingResource);
return @"XMPPIOS";
}

- (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq
{
NSLog(@"didReceiveIQ: %@",iq.description);
return YES;
}


在当前用户已经与后台openfire连接,但是状态是未登录状态,所以此时,当前用户发送状态告知后台,这样其他的用户才能收到当前用户的上线通知。

- (void)goOnline
{
XMPPPresence *presence = [XMPPPresence presence];
[xmppStream sendElement:presence];
}


f.当你成功上线后 你就会收到一堆在线用户的消息 然后代理方法疯狂的调用着




/接受到好友状态更新
//接收添加好友信息 available 上线 away 离开 do not disturb 忙碌 unavailable 下线
- (void)xmppStream:(XMPPStream *)sender didReceivePresence:(XMPPPresence *)presence
{
NSLog(@"好友状态更新:didReceivePresence: %@",presence.description);
}
- (void)xmppStream:(XMPPStream *)sender didReceiveError:(NSXMLElement *)error
{
NSLog(@"didReceiveError: %@",error.description);
}
- (void)xmppStream:(XMPPStream *)sender didSendIQ:(XMPPIQ *)iq
{
NSLog(@"didSendIQ:%@",iq.description);
}
- (void)xmppStream:(XMPPStream *)sender didSendPresence:(XMPPPresence *)presence
{
NSLog(@"didSendPresence:%@",presence.description);
}
- (void)xmppStream:(XMPPStream *)sender didFailToSendIQ:(XMPPIQ *)iq error:(NSError *)error
{
NSLog(@"didFailToSendIQ:%@",error.description);
}
- (void)xmppStream:(XMPPStream *)sender didFailToSendMessage:(XMPPMessage *)message error:(NSError *)error
{
NSLog(@"didFailToSendMessage:%@",error.description);
NSLog(@"发送失败,麻烦检查下网络");
}
- (void)xmppStream:(XMPPStream *)sender didFailToSendPresence:(XMPPPresence *)presence error:(NSError *)error
{
NSLog(@"didFailToSendPresence:%@",error.description);
}
- (void)xmppStreamWasToldToDisconnect:(XMPPStream *)sender
{
NSLog(@"xmppStreamWasToldToDisconnect");
}
- (void)xmppStreamConnectDidTimeout:(XMPPStream *)sender
{
NSLog(@"xmppStreamConnectDidTimeout");
}
- (void)xmppStreamDidDisconnect:(XMPPStream *)sender withError:(NSError *)error
{
NSLog(@"连接断开的时候:xmppStreamDidDisconnect: %@",error.description);
self.isXmppConnected = NO;
}


上面都是xmppstream的代理方法。好比最后一个DidDisconnect方法 就是在你与服务器断开连接时调用的。(有可能是你正常离线 也可能是你意外掉线)。

Over。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: