XMPP协议及实践
一、XMPP协议 XMPP (Extensible Messaging and Presence Protocol可扩展消息处理现场协议)是基于可扩展标记语言(XML)的协议,它用于即时消息(IM)以及在线现场探测。XMPP的前身是Jabber,基于XMPP的应用具有很强的可扩展性。 1、XMPP中的几个重要概念: JID:即Jabber ID。xmpp网络有一个或多个地址jid,如a@aaa.lit/study 。 组成:节点、域、资源(带有资源的jid是完整jid,没有资源的jid是裸jid),其中节点和资源是可选的,域是必选的。jid的资源部分会标识一个特定的客户端xmpp链接,对于xmpp客户端来说,每个链接均被指派一个资源。
XMPP中定义了三个角色,客户端,服务器,网关。
关于XMPP协议的一些细节,这里也只写了个大概。具体请参见“XMPP协议参考手册”,或查阅相关书籍。
(1)先建立一个stream,然后协商一堆安全之类的东西,中间通信过程就是客户端一个接一个的发送XML Stanza给服务器。 (2)服务器根据客户端发送的信息以及程序的逻辑,发送XML Stanza给客户端。(这个过程并不是一问一答的,任何时候都有可能从一方发信给另外一方。) (3)通信的最后阶段</stream>关闭流,关闭TCP/IP连接。 XMPP 是一种很类似于http协议的一种数据传输协议,它的过程就如同“解包装--〉包装”的过程,用户只需要明白它接收的类型,并理解它返回的类型,就可以很好的利用xmpp来进行数据通讯。
关于XMPP的一些扩展协议:http://xmpp.org/xmpp-protocols/xmpp-extensions/
二、XMPP环境 1、服务器软件 服务器软件列表:http://xmpp.org/xmpp-software/servers/ 用得最多的当是Openfire了。ejabberd也用的比较多。 关于Openfire的安装与配置,看下面的blog就可以了 http://www.52php.cn/article/p-fgdkyxhl-nh.html Windows下 http://www.52php.cn/article/p-wxmelrgi-mn.html Mac下
2、客户端软件 客户端软件主要用来自己做开发测试时使用。 客户端软件列表:http://xmpp.org/xmpp-software/clients/ 客户端使用Spark即可,登录时,先在服务器上多创建几个账号,然后直接登录其中一个,添加联系然即可进行聊天。 其他客户端软件参考Spark即可(最重要的是把JID输入正确) 参考下面文章:(仅供参考,没他写的那么复杂。第四步是另一回事,不用管) http://www.cnblogs.com/top5/archive/2009/04/07/1431001.html
三、XMPP基础实践 1、iOS上用XMPP开发IM软件 XMPP开发即自己做客户端连接XMPP服务器,实现点对点,群聊等功能。这里只是做一些基本的操作,具体细节还需要根据软件的业务来做。 XMPPFramework:一个XMPP协议的OC实现。关于XMPPFramework的简介与使用,可以参考其github上官方wiki。 https://github.com/robbiehanson/XMPPFramework/wiki/IntroToFramework 1)XMPP Core XMPPFramework分为2部分,其一为XMPP Core,另一部分为extensions,即XEP‘s扩展。 XMPP Core中的一些类:(大部分类可以顾名思义) - XMPPStream
2)XMPPStream 在XMPPFramework中,核心类即为XMPPStream,它是一个非常基础的类。下面英文简绍了其他一些类的作用。 The heart of the framework is the XMPPStream class. This is the primary class you will be interacting with,and it is the class that all extensions and custom code will plug into. It has a number of interesting features designed to make the framework flexible,extensible,and easy to develop on top of. These will be discussed in more depth later in this document.
3)Elements: IQ,& Presence (节点元素) XMPPElement是继承自NSMXLElement的,继承关系如下。 XMPPIQ -> XMPPElement -> NSXMLElement -> NSXMLNode -> NSObject 框架同时提供了NSXMLElement+XMPP分类,使写起代码来更加清晰与好看。 [element attributeIntValueForName:@"age"]; 4)XMPPStream配置与连接 可分为以下几个步骤: ①配置连接 xmppStream.myJID = [XMPPJID jidWithString:@"user@myCompany.com"]; xmppStream.hostName = @"myCompany.com";或者 xmppStream.myJID = [XMPPJID jidWithString:@"user@dev1.myCompany.com"]; xmppStream.hostName = @"192.168.2.27"; ②添加代理(MulticastDelegate) [xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()]; ... [xmppStream removeDelegate:self]; ③添加组件(Modules) 可以添加以下组件(不限于) XMPPReconnect - automatically reconnects the stream if you get accidentally disconnected. 以下代码添加XMPPReconnect组件到stream中 xmppReconnect = [ [XMPPReconnect alloc] init]; // Optional configuration of xmppReconnect could go here. // The defaults are fine for our purposes. [xmppReconnect activate:xmppStream]; // You can also optionally add delegates to the module. [xmppReconnect addDelegate:self delegateQueue:dispatch_get_main_queue()]; // And that's all that is needed. // The module will receive any delegate methods it needs automatically // from the xmpp stream,and will continue to do its thing unless you deactivate it. ④连接 如果忘记设置属性,如JID,则会返回NO NSError *error = nil; if (![xmppStream connect:&error]) { NSLog(@"Oops,I probably forgot something: %@",error); } ⑤认证 当所有的连接握手结束后,xmppStreamDidConnect: 代理方法将会被调用,可在此处进行一些认证操作等。 - (void)xmppStreamDidConnect:(XMPPStream *)sender { [xmppStream authenticateWithPassword:password error:NULL]; } XMPPFramework中给的iPhoneXMPP项目可作为参考,关于如何配置参见http://www.cnblogs.com/uvsjoh/archive/2012/08/11/2633306.html https://github.com/funkyboy/Building-a-Jabber-client-for-iOS 好东西,不解释。 登录成功,上张图:(本机测试的话,注意在代码中配置host)
2、Android上用XMPP开发IM软件 Android中比iOS可参考的资料与源码更多。 几个基本概念: Spark :提供了客户端一个基本的实现,并提出了一个很好的插件架构,这对于开发者来说不能不说是一个福音。我强烈建议基于插件方式来实现你新增加的功能,而不是去改它的源代码,这样有利于你项目架构,把原始项目的影响降到最低。 XMPP协议的实现可能有很多,既然选择了使用Smack来做,那么自然看smack的文档来做是最好了。 1)Connect and Disconnect (连接) // Create the configuration for this new connection_ ConnectionConfiguration config = new ConnectionConfiguration("jabber.org",5222); AbstractXMPPConnection connection = new XMPPTCPConnection(config); // Connect to the server_ connection.connect(); // Log into the server_ connection.login("username","password","SomeResource"); ... // Disconnect from the server_ connection.disconnect(); By default Smack will try to reconnect the connection in case it was abruptly disconnected. Use ConnectionConfiguration#setReconnectionAllowed(boolean) to turn on/off this feature. The reconnection manager will try to immediately reconnect to the server and increase the delay between attempts as successive reconnections keep failing. In case you want to force a reconnection while the reconnetion manager is waiting for the next reconnection,you can just use AbstractXMPPConnection#connect() and a new attempt will be made. If the manual attempt also failed then the reconnection manager will still continue the reconnection job. (以上英文摘自smack文档。大意是:除非调用disconnect,默认情况下会重新连接,可以使用ConnectionConfiguration#setReconnectionAllowed(boolean)方法来关闭或者打开该特性。 重连管理器会立即重连,并增加延迟。如果想手动重新连接,使用AbstractXMPPConnection#connect() 方法,失败了还是会继续重连的)
2)Roster Entries (名册条目,即单个好友的实体标示) 每个用户被标示为一个Roster Entry,包含以下3部分。 - 一个XMPP地址,即JID。 - 用户的名字 -用户所属的组名 Roster roster = connection.getRoster(); Collection<RosterEntry> entries = roster.getEntries(); for (RosterEntry entry : entries) { System.out.println(entry); } 3)Listening for Roster and Presence Changes (监听与显示改变) Roster roster = con.getRoster(); roster.addRosterListener(new RosterListener() { // Ignored events public void entriesAdded(Collection<String> addresses) {} public void entriesDeleted(Collection<String> addresses) {} public void entriesUpdated(Collection<String> addresses) {} public void presenceChanged(Presence presence) { System.out.println("Presence changed: " + presence.getFrom() + " " + presence); } });
// Create a packet filter to listen for new messages from a particular // user. We use an AndFilter to combine two other filters._ PacketFilter filter = new AndFilter(new PacketTypeFilter(Message.class),new FromContainsFilter("mary@jivesoftware.com")); // Assume we've created a XMPPConnection name "connection". // First,register a packet collector using the filter we created. PacketCollector myCollector = connection.createPacketCollector(filter); // Normally,you'd do something with the collector,like wait for new packets. // Next,create a packet listener. We use an anonymous inner class for brevity. PacketListener myListener = new PacketListener() { **public** **void** processPacket(Packet packet) { // Do something with the incoming packet here._ } }; // Register the listener._ connection.addPacketListener(myListener,filter); 以上是一些基本的操作,需要引入jar包。 http://download.csdn.net/detail/sky_monkey/5820879 (Android小例子) 说明: XmppTool是负责连接服务器的工具类;(自己测试的话修改ip,或者在host文件中进行映射也可以) FormLogin负责登录; FormCilent负责登录后接受聊天消息冰显示; FormFiles传文件。 连接后得到ChatManager,然后通过JID与特定用户进行聊天会话。(源码中自己修改相应的JID)
参考: RFC3920_XMPP中文翻译规范 (百度文库) http://www.igniterealtime.org/index.jsp smack官方文档 http://www.52php.cn/article/p-fgdkyxhl-nh.html 4篇XMPP Android系列 https://github.com/robbiehanson/XMPPFramework/wiki/GettingStarted_iOS XMPPFramework https://github.com/robbiehanson/XMPPFramework/wiki/IntroToFramework XMPPFramework使用 http://www.cnblogs.com/uvsjoh/archive/2012/08/11/2633306.html XMPPFrame Demo使用注意 http://code4app.com/ios/xmpp-for-ios/521705756803fa7c32000006 iOS http://www.cnblogs.com/PhenixWang/p/3275454.html XMPP iOS http://www.52php.cn/article/p-vfpwklkr-beg.html 4篇XMPP iOS系列 http://code4app.com/search/XMPP 几个源码
转载请注明出处:http://blog.csdn.net/xn4545945 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |