因为在之前项目需要用到即时聊天的功能.在逛了好多论坛之后,才终于实现了即时聊天的功能。
使用xmpp+openfire+iOS客户端来制作聊天app的demo、教程网上都有很多,在这里简单地说一下核心做法。
1. 首先就要制作服务器,这块我是用的openfire的服务器,数据库也不是用嵌入在openfire里面的,而是用的mySQL,性能相当不错,而且不会丢消息。
1.1 到http://www.igniterealtime.org/downloads/index.jsp去下载最新的openfire
为了验证服务器搭建完成没有,或者验证app到底能不能正常通信,可以下Spqrk来试验,它就是一个聊天工具,等登陆上且能给手机模拟器正常聊天,那聊天功能就成功了!
1.2 安装openfire,本人是在Mac10.10下安装的,之后去用户偏好里面就能打开设置页,设置好了就能够拿电脑当服务器使了,而windows跟linux的没有用过,不过网上很多教程这里转发一个:http://wiki.jabbercn.org/Openfire:%E5%AE%89%E8%A3%85%E6%8C%87%E5%8D%97
再发一个在mac上搭建的教程: http://www.cnblogs.com/xiaodao/archive/2013/04/05/3000554.html
好了,到这里服务器应该已经搭建好了,使用spark去登陆一下。
2. iOS端制作
2.1 导入框架,iOS端使用xmpp需要导入对应的库: XMPPFramework ,这个库在Github、code4app上面都有,导入过程也不复杂,但是本人还是习惯性的去使用CocoaPods,
毕竟用来导入实在太方便了。CocoaPods是一种开发工具,在终端上几行代码就能够给项目导入好库,有依赖的库也会给导入好,具体教程网上一抓一大把。
2.2 大家应该已经猜出来了,其实就是使用XMPPFramework里面的代理方法和xmppStream来跟服务器发送和收到消息。
先建立跟服务器的连接:
然后连接服务器:
PS:如果服务器不是自己电脑,需要把Server给改成服务器的IP地址。
记得给实现XMPPStreamDelegate,当服务器发送消息,比如别人发的消息、好友上线消息等都会回调里面的方法,之前建立连接的时候设定的delegate就是让服务器回调的时候能有回调的方法给执行。
需要实现的有:
#pragma mark -- XMPPStream Delegate
//连接服务器
- (void)xmppStreamDidConnect:(XMPPStream *)sender{
NSLog(@"did Connected");
NSError *error = nil;
//验证密码
if (![[self xmppStream] authenticateWithPassword:password error:&error]){
NSLog(@"Authenticate Error: %@", [[error userInfo] description]);
}
}
//验证通过
- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender{
NSLog(@"验证已通过.........");
[self goOnline];
}
//收到消息
- (void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message{
// NSLog(@"message = %@", message);
NSString *msg = [[message elementForName:@"body"] stringValue];
NSString *from = [[message attributeForName:@"from"] stringValue];
NSLog(@"receive message :%@ from :%@",msg, from);
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setObject:msg forKey:@"MSG"];
[dict setObject:from forKey:@"SENDER"];
//消息委托,就是收到的消息怎么处理
[self.messageViewController MessageReceived:dict];
}
//收到好友状态
- (void)xmppStream:(XMPPStream *)sender didReceivePresence:(XMPPPresence *)presence{
//取得好友状态
NSString *presenceType = [presence type]; //online/offline
//当前用户
NSString *userId = [[sender myJID] user];
//在线用户
NSString *presenceFromUser = [[presence from] user];
NSLog(@"id: %@",userId);
NSLog(@"user: %@", presenceFromUser);
NSLog(@"type: %@", presenceType);
/*这里应该做当有好友上线之后的操作,比如改变对应头像颜色之类的*/
}
- (void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(NSXMLElement *)error {
NSLog(@"did not authenticate....error :%@", error);
UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:@"错误" message:@"账号/密码输入出错!" delegate:nil cancelButtonTitle:@"cancel" otherButtonTitles:nil];
[alertView show];
}
做到这里就能收到消息了,建议都给放在appDelegate上面,这样xmppStream不会被释放掉
下面是发送消息功能的实现
- (IBAction)sendClick:(id)sender {
NSString *message = self.messageTextField.text;
NSMutableString *toName = [NSMutableString stringWithString:self.toTextField.text];
[toName appendString:@"@127.0.0.1"];
//xmpp通过kissxmpp来上传消息
if (message.length > 0) {
//下面几行就是自己发送消息之后做的事(屏幕上给出现自己发的消息)
NSMutableString *messages = [NSMutableString stringWithString:self.messageTextView.text];
NSString *selfName = [[NSUserDefaults standardUserDefaults] stringForKey:@"USERID"];
[messages appendString:[NSString stringWithFormat:@"\n %@",selfName]];
[messages appendString:[NSString stringWithFormat:@"\n %@", self.messageTextField.text]];
self.messageTextView.text = messages;
//生成文档
NSXMLElement *body = [NSXMLElement elementWithName:@"body"];
[body setStringValue:message];
//生成XML消息文档
NSXMLElement *mes = [NSXMLElement elementWithName:@"message"];
//消息类型
[mes addAttributeWithName:@"type" stringValue:@"chat"];
//发送给谁
[mes addAttributeWithName:@"to" stringValue:toName];
//由谁发送
[mes addAttributeWithName:@"from" stringValue:[[NSUserDefaults standardUserDefaults] stringForKey:@"USERID"]];
//组合
[mes addChild:body];
//发送消息
[[self xmppStream] sendElement:mes];
self.messageTextField.text = @"";
[self.messageTextField resignFirstResponder];
}
}