即时通讯技术(IM)支持用户在线实时交谈。如果要发送一条信息,用户需要打开一个小窗口,以便让用户及其朋友在其中输入信息并让交谈双方都看到交谈的内容。大多数常用的即时通讯发送程序都会提供各种各样的功能:
有许多的IM系统,如AOLIM、YahooIM和MSNIM,它们使用了不同的技术,而且它们互不兼容。为了创建即时通讯的统一标准,人们经过了多次尝试:IETF的对话初始协议(SIP)和即时通讯对话初始协议和表示扩展协议(SIMPLE)、应用交换协议(APEX)、显示和即时通讯协议(PRIM)及基于XML且开放的可扩展通讯和表示协议(XMPP)协议(常称为Jabber协议)。人们多次努力,试图统一各大主要IM供应商的标准(AOL、Yahoo及Microsoft),但无一成功,且每一种IM仍然继续使用自己所拥有的协议。
这些常用的即时通讯传送协议如下:
-
可扩展通讯和表示协议(XMPP):用于流式传输准实时通信、表示和请求-响应服务等的XML元素。XMPP基于Jabber协议,是用于即时通讯的一个开放且常用的协议。尽管XMPP没有被任何指定的网络架构所融合,它还是经常会被用于客户机/服务器架构当中,客户机需要利用XMPP协议通过TCP连接来访问服务器,而服务器也是通过TCP连接进行相互连接。
-
即时通讯对话初始协议和表示扩展协议(SIMPLE):SIMPLE协议为SIP协议指定了一整套的架构和扩展方面的规范,而SIP是一种网际电话协议,可用于支持IM/消息表示。SIP能够传送多种方式的信号,如INVITE信号和BYE信号分别用于启动和结束会话。SIMPLE协议在此基础上还增加了另一种方式的请求,即MESSAGE信号,可用于发送单一分页的即时通讯内容,即分页模式的即时通讯。SUBSCRIBE信号用于请求把显示信息发送给请求者,而NOTIFY信号则用于传输显示信息。较长IM对话的参与者们需要传输多种的延时信息,它们使用INVITE和一个叫做消息会话中继协议(MSRP)。与SIMPLE协议结合,MSRP协议可用于IM的文本传输,正如与SIP协议相结合,RTP协议就可以用于传输IP电话中的语音数据包一样。
-
Jabber:Jabber是一种开放的、基于XML的协议,用于即时通讯消息的传输与表示。国际互联网中成千上万的服务器都使用了基于Jabber协议的软件。Jabber系统中的一个关键理念是“传输”,也叫做“网关”,支持用户使用其它协议访问网络—如AIM和ICQ、MSNMessenger和WindowsMessenger、SMS或E-mail。
-
即时通讯通用结构协议(CPIM):CPIM定义了通用协议和消息的格式,即时通讯和显示服务都是通过CPIM来达到IM系统中的协作。
网际转发聊天协议(IRCP):IRCP支持两个客户计算机之间、一对多(全部)客户计算机和服务器对服务器之间的通信。该协议为大多数网际即时通讯和聊天系统提供了技术基础。IRC协议在TCP/IP网络系统中已经得到了开发,尽管没有需求指定这是IRC协议的唯一操作环境。IRC协议是一种基于文本的协议,使用最简单的客户端程序就可作为其连接服务器的接口(socket)程序。
XMPP开发相关参考资料
http://strophe.im/
http://strophe.im/strophejs/
XMPP客户端库,包括javascript和C的实现
https://github.com/ging/social_stream/wiki/Getting-Started-With-Social-Stream-Presence
一篇讲架构的文章,图文并茂
http://xmpp.org/xmpp-software/libraries/
许多相关的库
http://stackoverflow.com/questions/4769020/android-and-xmpp-currently-available-solutions
Android与XMPP
设计基于开源的XMPP即时通信协议,采用C/S体系结构,通过GPRS无线网络用TCP协议连接到服务器,以架设开源的Openfn'e服务器作为即时通讯平台。
系统主要由以下部分组成:一是服务器,负责管理发出的连接或者与其他实体的会话,接收或转发XML(ExtensibleMarkupLanguage)流元素给授权的客户端、服务器等;二是客
户终端。它与服务器相连,通过XMPP获得由服务器或任何其它相关的服务所提供的全部功能。三是协议网关。完成XMPP协议传输的信息与外部消息系统可识别信息间的翻译。再就是XMPP网络。实现各个服务器、客户端间的连接。系统采用客户端(Client)/服务端(Server)架构体系结构。
客户端:
客户端基于Android平台进行开发。负责初始化通信过程,进行即时通信时,由客户端负责向服务器发起创建连接请求。系统通过GPRS无线网络与Internet网络建立连接,通过服务器实现与Android客户端的即时通信脚。
服务器端:
服务器端则采用Openfire作为服务器。允许多个客户端同时登录并且并发的连接到一个服务器上。服务器对每个客户端的连接进行认证,对认证通过的客户端创建会话,客户
端与服务器端之间的通信就在该会话的上下文中进行。
1.1服务器端设计(这块几乎可以说是有成品了。不用多纠结)
androidpn服务器端是java语言实现的,基于openfire开源工程,Web部分采用的是spring框架,这一点与openfire是不同的。Androidpn服务器包含两个部分,一个是监听特定端口上的XMPP服务,负责与客户端的XMPPConnection类进行通信,作用是用户注册和身份认证,并发送推送通知消息。另外一部分是Web服务器,采用一个轻量级的HTTP服务器,负责接收用户的Web请求。
主要的四个组成部分,分别是SessionManager,AuthManager,PresenceManager以及NotificationManager。SessionManager负责管理客户端与服务器之间的会话,AuthManager负责客户端用户认证管理,PresenceManager负责管理客户端用户的登录状态,NotificationManager负责实现服务器向客户端推送消息功能。
系统客户端基于Android手机平台。采用XMPP作为即时通讯协议。XMPP是基于XML,实现任意两个网络终端准实时的交换结构化信息的通信协议。采用Android平台提供的XML解析包对XML进行解析。由于应用活动都运行于主线程。故用多线程技术来解决系统通讯问题。针对通信安全问题.系统的用户信息和聊天信息在客户端存储在Android平台自身所带的sqlite数据库中,多媒体文件和图片文件存储在Android平台虚拟文件存储设备SDCard中。
通讯模块负责与服务器建立通讯旧。通过创建3个线程来进行处理。分别负责消息的发送、接收和心跳信息的发送;解析模块主要用来解析XML数据流。根据解析元素不同类型封装成不同的数据对象:数据模块定义整个客户端中大部分的数据类型和对象;应用模块包括即时通信、图片浏览和音乐播放。是客户端和用户交流的接口;加密模块对发送和接收的消息进行加解密。以确保通讯数据的安全。
系统的客户端分为5大模块进行设计开发,如图2所示。
加密(首先将二进制码转换成BASE64码,在转换成BASE64码之后,再进行MD5加密,)
XMPP服务器之间、客户与服务器之间采用的是TCP连接罔。TCP提供一种瓦向连接、可靠的字节流服务。保持一个实时双向的传输通道。TCP将用户数据打包构成报文段。它发送数据后启动一个定时器,等待对端数据确认,另一端对收到的数据进行确认,对失序的数据重新排序,并丢弃重复数据;TCP提供端到端的流量控制。计算和验证一个强制性的端到端检验。但是GPRS网络对TCP链路存在一个限制。当TCP链路在长时间无有数据流量时。会自动降低此链路的优先级直至强制断开此链路。所以在应用中.采用发送心跳的方式来维持此链路。
数据格式
XML是XMPP系统架构的核心。它能表述几乎任何一种结构化数据。特别是XMPP利用XML数据流进行客户端一服务器端、服务器端一服务器端的通信。XML数据流一般是由客户端发起至服务端,XML数据流的有效时间直接与用户的在线会话有效时间相关联。
协议消息格式
XMPP协议包括3个顶层XML元素:Message、Presence和IQm。Message用来表示传输的消息,当用户发送一条消息时。就会在流的上下文中插入一个Message元素,中间有用户发送的相关信息;Presence用来表示用户的状态。当用户改变自己的状态时。就会在数据流的上下文中插入一个Presence元素,用来表示用户现在的状态;IQ用来表示一种请求,响应机制,从一个实体发送请求,另外一个实体接受请求并响应。
后台Servic:
从类的层次看这个结构比较简单,让其变得复杂的是,其里面有三个线程:主线程,进行Xmpp通信线程,连接出错重试线程。
对图说明:
1.在NotificationService里创建一个单线程,让其对服务器进行连接,由于使用Xmpp连接服务器要分为三步:连接,注册,登陆。所以用一个栈来保存要执行的Task任务(ConnectTask,RegisterTask,LoginTask),还后再按这个顺序进行执行。
2.连接Xmpp服务器的线程用的是Executors.newSingleThreadExecutor(),这个本身可以不停的submit任务。为什么还要自己用一个栈来保存Task了
3.连接线程在连接,注册,登陆的过程中,都有可能出错,都可能会失败,这时我就要有一个重连的机制,在Androidpn里开了另外一个线程来进行重试,其重试不是每次都按多少秒来进行重试,而是有其自己的规则。
4.在LoginTask里,如果登陆了服务器端,其就会注册一个监听器,用于监听服务器push的数据包(Packet),再通过发送广播的方式来通知要进行显示的程序。
5.在登陆服务器后,也有可能出错,所以在登陆后,会设置一个ConnectionListener,用于监听连接出错的时候,再合适重连线程,进行重连
6.在登陆过程中,有一种错误要单独处理,就是账号和密码无效的时候,这个时候其返回的状态码是401,这种情况应该把本地保存的帐号和密码都清掉,再重新进行连接,不然会永远都登陆不上服务器端。
由于该系统所有的功能实现都是基于网络间的XML流的通信,所以,需要有一个模块专门负责网络问通信和XML流的处理,主要功能包括服务器和客户端之问通信时TCP套接字的处理,XML流的解析、存储等功能。
数据模块负责XML流的解析和封装的XML模块,主要功能是:将XML流解析成java对象,将iava对象封装成XML流;
其流程是XMPP服务器接收到XML流之后,会有渎取器将其读取出来并将其作为入口参数传入XML解析器,XML解析器通过对其命名空间的解析,从而确定将剩余的XML元素解析出来并传入相应的;ava对象中,从而最终将XML转换成iava对象,然后将iava对象传入应用程序模块中,实现其请求完成的功能并返回iava对象,但是该iava对象不能在网络中直接传输,必须先转换成XML节,于是,该iava对象会被传入XML封装器中,被封装成XML节,通过XMPP服务器的发送端口发往目的节点。
java对象处理模块处理流程如下:当该模块接收到iava对象时,会先将该对象通过解密算法和解密密钥解密成base64码,然后f耳将base64码转换成二进制码,从而实现对java对象的解析。当完成业务逻辑处理后,该模块会将返回的java对象先由二进制码转换成base64码,然后用加密算法将其加密,这里的加密算法是由双方在建立会话时通过三次握手协议协商的。
当XML节被封装成java对象后,必须被转发至订:确的模块中加以处理,这就要求有一个路由转发模块,如图3—3所示。该模块的实现原理是:在系统启动时加载该路由模块,从而在内存中创建了一块路由模块,记录了命名空和功能模块之间的对应关系,当iava对象被封装好之后,系统会读出其命名空间,再在路由表中查找其所对应的模块,从而动态地加载该模块,并将该java对象转发至该模块,从而实现路山转发的功能