xmpp协议的实现

来源:互联网 发布:网络用语af是什么意思 编辑:程序博客网 时间:2024/05/19 21:16

查了资料发现 现在的聊天服务器有开源的 有很多种 很多都是机遇xmpp协议来实现的,xmpp的前身是什么jabber 这个就自己去百度了 我用的一个开源服务器是 openfire 他有 linux macwindow版本 他的安装都是比较简单的就部介绍了 网上找到了这个很好的博客 

http://www.cnblogs.com/dyingbleed/archive/2013/05/09/3069145.html 

http://blog.csdn.net/ihefe/article/details/8230414

想想其实他的实现方式 还是相对比较简单的 很多都是靠xmpp自己来实现的我们只要在协议方法里面获得数据 其他的我们都不用考虑

实现xmpp  要用到一个框架自己到网上去下载   

XMPPFramework

网上下的demo要修改几个地方  一个是要连接的服务器的地址 本及其的话就127.0.0.1 其他地方的话 就对应他的ip  还有一点就是 域名的概念 登陆的用户名 是这样的格式 :用户名@域名 域名可以在你的openfire的服务器设置里面查看

 

(以下代码为了方便使用-调用都写在appdeleage里面)

第一步:算是初始化吧

.h里面

 

 

[html] view plaincopy
  1. #import <</span>UIKit/UIKit.h>  
  2. #import "XMPPFramework.h"  
  3. @interface AppDelegate UIResponder <</span>UIApplicationDelegate>  
  4.  
  5.     //    XMPPStream *xmppStream;  
  6.     //    XMPPRoster *xmppRoster;  
  7.     //    XMPPRosterCoreDataStorag*xmppRosterStorage;  
  8.     //    XMPPReconnect *xmppReconnect;  
  9.     //    XMPPMessageArchivingCoreDataStorage *xmppMessageArchivingCoreDataStorage;  
  10.     //    XMPPMessageArchiving *xmppMessageArchivingModule;  
  11.       
  12.       
  13.       
  14.     XMPPReconnect *xmppReconnect;  
  15.     XMPPStream *xmppStream;  
  16.     XMPPvCardCoreDataStorage*xmppvCardStorage  
  17.     XMPPvCardTempModule*xmppvCardTempModule  
  18.     XMPPvCardAvatarModule* xmppvCardAvatarModule  
  19.       
  20.     // 初始化 capabilities  
  21.       
  22.       
  23.     XMPPCapabilitiesCoreDataStorage xmppCapabilitiesStorage  
  24.     XMPPCapabilities* xmppCapabilities;  
  25.     XMPPRosterCoreDataStorage*  xmppRosterStorage;  
  26.     //  xmppRosterStorage [[XMPPRosterCoreDataStoragalloc] initWithInMemoryStore];  
  27.     BOOL isXmppConnected;  
  28.     NSString *password;  
  29.     XMPPRoster* xmppRoster  
  30.       
  31.     XMPPMessageArchivingCoreDataStorage *xmppMessageArchivingCoreDataStorage;  
  32.     XMPPMessageArchiving *xmppMessageArchivingModule;  
  33.       
  34.     BOOL allowSelfSignedCertificates;  
  35.     BOOL allowSSLHostNameMismatch 
  36.  
  37. //---------------------------------------------------------------------  
  38. @property (nonatomic, strong) XMPPStream *xmppStream;  
  39. @property (nonatomic, strong) XMPPRosterCoreDataStorag*xmppRosterStorage;  
  40. @property (nonatomic, strong) XMPPRoster *xmppRoster;  
  41. @property (nonatomic, strong) XMPPReconnect *xmppReconnect;  
  42. @property (nonatomic, strong) XMPPMessageArchivingCoreDataStorage *xmppMessageArchivingCoreDataStorage;  
  43. @property (nonatomic, strong) XMPPMessageArchiving *xmppMessageArchivingModule;  
  44. @property (strong, nonatomic) UIWindow *window;  
  45. (BOOL)connect:(NSString *)loginName;  
  46. -(void)showAlertView:(NSString *)message;  
  47.   
  48. @property (nonatomic, strong) NSMutableArray *friendArray;  
  49. @end  


 


.m里面

 

 

[html] view plaincopy
  1. (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions  
  2.  
  3.     [self setupStream];  
  4.     return YES;  
  5.  
  6. (void)setupStream  
  7.  
  8.     NSAssert(xmppStream == nil, @"Method setupStream invoked multiple times");  
  9.       
  10.     // 初始化XmppStream  
  11.       
  12.     xmppStream [[XMPPStream alloc] init];  
  13.       
  14. #if !TARGET_IPHONE_SIMULATOR  
  15.      
  16.         // 想要xampp在后台也能运行?  
  17.         //  
  18.         // P.S. 虚拟机不支持后台  
  19.           
  20.         xmppStream.enableBackgroundingOnSocket YES 
  21.      
  22. #endif  
  23.       
  24.     // 初始化 reconnect  
  25.     //  
  26.     // 这东西可以帮你把意外断开的状态连接回去...具体看它的头文件定义  
  27.       
  28.     xmppReconnect [[XMPPReconnect alloc] init];  
  29.       
  30.     // 初始化 roster  
  31.       
  32.     xmppRosterStorage [[XMPPRosterCoreDataStoragalloc] init];  
  33.     //  xmppRosterStorage [[XMPPRosterCoreDataStoragalloc] initWithInMemoryStore];  
  34.       
  35.     xmppRoster [[XMPPRoster alloc] initWithRosterStorage:xmppRosterStorage];  
  36.       
  37.     xmppRoster.autoFetchRoster YES 
  38.     xmppRoster.autoAcceptKnownPresenceSubscriptionRequests YES 
  39.       
  40.     // 初始化 vCard support  
  41.       
  42.     xmppvCardStorage [XMPPvCardCoreDataStorage sharedInstance];  
  43.     xmppvCardTempModule [[XMPPvCardTempModule alloc] initWithvCardStorage:xmppvCardStorage];  
  44.       
  45.     xmppvCardAvatarModule [[XMPPvCardAvatarModule alloc] initWithvCardTempModule:xmppvCardTempModule];  
  46.       
  47.     // 初始化 capabilities  
  48.       
  49.       
  50.     xmppCapabilitiesStorage [XMPPCapabilitiesCoreDataStorage sharedInstance];  
  51.     xmppCapabilities [[XMPPCapabilities alloc] initWithCapabilitiesStorage:xmppCapabilitiesStorage];  
  52.       
  53.     xmppCapabilities.autoFetchHashedCapabilities YES 
  54.     xmppCapabilities.autoFetchNonHashedCapabilities NO 
  55.       
  56.     // 激活xmpp的模块  
  57.       
  58.     [xmppReconnect         activate:xmppStream];  
  59.     [xmppRoster            activate:xmppStream];  
  60.     [xmppvCardTempModule   activate:xmppStream];  
  61.     [xmppvCardAvatarModule activate:xmppStream];  
  62.     [xmppCapabilities      activate:xmppStream];  
  63.       
  64.     // 我们可以加添加委托来获取我们感兴趣的东西  
  65.       
  66.     [xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];  
  67.     [xmppRoster addDelegate:self delegateQueue:dispatch_get_main_queue()];  
  68.       
  69.     // 下面可以替换成自己的域名和端口  
  70.       
  71.     // 如果你没有提供一个地址,JID也是一样可以代替的,JID的格式类似这样"用户名@域名/roster",框架会自动抓取域名作为你的地址  
  72.       
  73.     // 如果没有设置特殊的端口,默认为5222  
  74.       
  75.     [xmppStream setHostName:@"223.4.32.64"];//AY130618164649Z  
  76.     [xmppStream setHostPort:5222];  
  77.       
  78.       
  79.     //下面这两个根据你自己配置需要来设置  
  80.     allowSelfSignedCertificates NO 
  81.     allowSSLHostNameMismatch NO 
  82.  


 

//连接的代码

//连接到openfire

- (BOOL)connect:(NSString *)loginName{

   NSString *jid=loginName;

   NSString *ps= @"123";//没用

   if (jid== nil || ps==nil) {

      return NO;

    }

   if (jid== nil || ps==nil) {

      return NO;

    }

   XMPPJID *myjid= [XMPPJIDjidWithString:jid];

   NSError *error;

    [xmppStreamsetMyJID:myjid];

   if (![xmppStreamconnectWithTimeout:XMPPStreamTimeoutNoneerror:&error]){

      NSLog(@"my connected error :%@",error.description);

      return NO;

    }

   return YES;

}

以下是主要的一些会使用到的方法

[html] view plaincopy
  1. //将要连接  
  2. (void)xmppStreamWillConnect:(XMPPStream *)sender  
  3.  
  4.     NSLog(@"xmppStreamWillConnect");  
  5.  
  6. //已经连接  
  7. (void)xmppStreamDidConnect:(XMPPStream *)sender  
  8.  
  9.     NSLog(@"xmppStreamDidConnect");  
  10.     NSError *error  
  11.     if (![self.xmppStream authenticateWithPassword:@"123" error:&error]) //密码跟 abc@127.0.0.1 的密码对应  
  12.         NSLog(@"error authenticate %@",error.description);  
  13.      
  14.  
  15.   
  16. //注册  
  17. (void)xmppStreamDidRegister:(XMPPStream *)sender  
  18.  
  19.     NSLog(@"xmppStreamDidRegister");  
  20.       
  21.     NSError *error  
  22.     if (![self.xmppStream authenticateWithPassword:@"123" error:&error])  
  23.         NSLog(@"error authenticate %@",error.description);  
  24.      
  25.  
  26. -(void)goOnline{  
  27.       
  28.     //发送在线状态  
  29.     XMPPPresence *presence [XMPPPresence presence];  
  30.     [[self xmppStream] sendElement:presence];  
  31.       
  32.  
  33. (void)goOffline  
  34.  
  35.     XMPPPresence *presence [XMPPPresence presenceWithType:@"unavailable"];  
  36.       
  37.     [[self xmppStream] sendElement:presence];  
  38.  
  39.   
  40. (void)xmppStream:(XMPPStream *)sender didNotRegister:(NSXMLElement *)error  
  41.  
  42.     [self showAlertView:@"当前用户已经存在"];  
  43.  
  44. //上线  
  45. (void)xmppStreamDidAuthenticate:(XMPPStream *)sender  
  46.  
  47.     [self goOnline];  
  48.  
  49. (void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(NSXMLElement *)error  
  50.  
  51.     NSLog(@"didNotAuthenticate:%@",error.description);  
  52.  
  53. (NSString *)xmppStream:(XMPPStream *)sender alternativeResourceForConflictingResource:(NSString *)conflictingResource  
  54.  
  55.     NSLog(@"alternativeResourceForConflictingResource: %@",conflictingResource);  
  56.     return @"XMPPIOS";  
  57.  
  58. //获取到好友列表  
  59. (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq  
  60.  
  61.     NSString *str=@"";  
  62.     self.friendArray =[[NSMutableArray alloc] init];  
  63. //    NSLog(@"获取到好友列表didReceiveIQ: %@",iq.description);  
  64.     if ([@"result" isEqualToString:iq.type])  
  65.         NSXMLElement *query iq.childElement;  
  66.         if ([@"query" isEqualToString:query.name])  
  67.             NSArray *items [query children];  
  68.             for (NSXMLElement *item in items)  
  69.                 NSString *jid [item attributeStringValueForName:@"jid"];  
  70.                 XMPPJID *xmppJID [XMPPJID jidWithString:jid];  
  71.                 NSLog(@"好友:%@",xmppJID);  
  72.                 str [NSString stringWithFormat:@"%@\n%@",str,xmppJID];  
  73.                 [self.friendArray addObject:[NSString stringWithFormat:@"%@",xmppJID]];  
  74.              
  75.             //通知   
  76.             [[NSNotificationCenter defaultCenter] postNotificationName:@"user" object:nil userInfo:[NSDictionary dictionaryWithObject:self.friendArray forKey:@"userlist"]];  
  77.          
  78.      
  79.   
  80.     return YES;  
  81.  
  82. //收到信息  
  83. (void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message  
  84.  
  85.     NSString *msg [[message elementForName:@"body"] stringValue];  
  86.     NSString *from [[message attributeForName:@"from"] stringValue];  
  87.     NSLog(@"消息内容:\n%@  信息来源:\n%@ ",msg,from);  
  88.    NSString *str [NSString stringWithFormat:@"消息内容:\n%@  信息来源:\n%@ ",msg,from];  
  89.     UIAlertView *alert [[UIAlertView alloc] initWithTitle:@"好友" message:str delegate:nil cancelButtonTitle:@"ok" otherButtonTitles:nil, nil];  
  90.     [alert show];  
  91.     [[NSNotificationCenter defaultCenter] postNotificationName:@"userMSG" object:nil userInfo:[NSDictionary dictionaryWithObject:str forKey:@"MSG"]];  
  92.  
  93. //获取好友状态,通过实现  
  94. //available 上线  
  95. //away 离开  
  96. //do not disturb 忙碌  
  97. //unavailable 下线  
  98. (void)xmppStream:(XMPPStream *)sender didReceivePresence:(XMPPPresence *)presence  
  99.  
  100.     //取得好友状态  
  101.     NSString *presenceType [presence type]; //online/offline  
  102.     //当前用户  
  103.     // NSString *userId [[sender myJID] user];  
  104.     //在线用户  
  105.     NSString *presenceFromUser [[presence from] user];  
  106.       
  107.     NSLog(@"状态:%@  帐号:%@",presenceType,presenceFromUser);  
  108.  

 这里要强调一个 方法

 

- (void)xmppStream:(XMPPStream *)senderdidReceivePresence:(XMPPPresence *)presence

这个协议方法是获取好友的状态的我发现 只有  有好友是在线的  他才会调用!

注册注意点

 要先创建一个匿名的连接才可以进行注册

 

  [[selfappDelegateconnect:@"匿名连接"];


//获取appdelegate的连接方法

- (AppDelegate *)appDelegate

{

return (AppDelegate *)[[UIApplicationsharedApplicationdelegate];

}

注册代码

- (IBAction)RegAction:(id)sender {

   NSError *error;

   if ([[[selfappDelegatexmppStream]isConnected]&& [[[selfappDelegate]xmppStream]supportsInBandRegistration])

    {

      [[selfappDelegate].xmppStreamsetMyJID:[XMPPJIDjidWithUser:self.userName.textdomain:@"AY130618164649Z"resource:@"xmpp"]];

      //       [[selfappDelegate]setIsRegistration:YES];

      if (![[selfappDelegate].xmppStreamregisterWithPassword:@"123"error:&error]){

          [[selfappDelegateshowAlertView:[NSStringstringWithFormat:@"%@",error.description]];

       }

      UIAlertView *alert =[[UIAlertViewallocinitWithTitle:@"Success"message:@"ResgisterSuccess"delegate:nilcancelButtonTitle:@"OK"otherButtonTitles:nil,nil];

       [alertshow];

    }

   else

    {

      UIAlertView *alert =[[UIAlertViewallocinitWithTitle:@"Fail"message:@"ResgisterFail"delegate:nilcancelButtonTitle:@"OK"otherButtonTitles:nil,nil];

       [alertshow];

    }


}



登陆的代码

 

- (IBAction)connectAction:(id)sender{

    //断开连接

    [[[selfappDelegatexmppStream]disconnect];

    //重新请求连接登陆

    [[selfappDelegateconnect:self.loginName.text];

    //接受好友列表的通知

    [[NSNotificationCenterdefaultCenter]addObserver:selfselector:@selector(show:)name:@"user"object:nil];

     [self.loginNameresignFirstResponder];

}

添加好友的代码

 

//添加好友

- (IBAction)AddAction:(id)sender {

    [[[selfappDelegatexmppRoster]addUser:[XMPPJIDjidWithString:[NSStringstringWithFormat:@"%@@AY130618164649Z",self.jidName.text]]withNickname:self.jidName.text];

}

//AY130618164649Z  ===》域名
0 0