即时通讯在移动互联网上的实现

摘要:该文讨论了基于Jabber协议的即时通讯在手机上的实现,详细介绍了客户端应用程序与服务器之间的通信过程。

关键词:IM;HTTP;J2ME;Jabber;XML

中图分类号:TP393文献标识码:A文章编号:1009-3044(2010)20-5661-04

Instant Message Applies Combined Set

HU Wen-sheng1, LI Guo-hua2, HU Yan-ping2

(1. Commercial College of Guizhou, Guiyang 550000, China; 2. Hunan Xinning No2 Middle School, Xinning 422713, China)

Abstract: This thesis discusses that Instant Message on the base of Jabber Protocol applies Combined Set and introduces the process of communication between client and server.

Key words: IM; HTTP; J2ME; Jabber; XML

本文讨论了基于Jabber协议的即时通讯在手机上的应用,详细介绍了各种移动终端设备的客户端程序与服务器端之间通过互联网及移动数据网进行实时多媒体互动交流。不仅可以传输文本信息,更可实现图像、音频、视频的互动,同时还可以收发电子邮件。

1 基本概念

1.1 即时通讯(IM)

即时通讯也叫即时消息传递(Instant Message ,IM)是基于互联网协议的应用程序,它能够使应用不同类型设备的用户一对一进行通信。IM最流行的形式是聊天,在聊天的同时可以在计算机之间交换短文本消息。目前在国内用得最广、深受广大网民喜爱的即时通讯产品要算腾讯QQ和微软的MSN了。随着无线应用协议(Wireless Application Protocol,WAP)和移动电话类的手持设备的出现,即时通讯越来越多的应用于各种移动电话上。

1.2 Jabber XML协议的结构

Jabber即时通讯系统与其他即时通讯不同,它是基于源代码开放的XML协议。这样的好处是使超长传输的分布性更好也更易访问。客户端程序与服务器之间的通信发生在指定的端口上,在交换数据时,构造各种符合Jabber XML协议的数据包,以XML流的形式进行传递。 Jabber的开放式XML协议包括三个顶层XML元素(也称为标记):

,此元素用来确定用户的状态。其格式为:Onlinenone-audio。表明9054这个用户发送给用户为9063,同时也表明了用户9054的状态。

,此元素用来包含两个Jabber用户间互相发送消息的内容。其格式为:aaaaaaa22222222

,此元素的意思是信息/查询。该元素主要是用来在两个用户之间构建一个根本的会话,并且允许它们来回传送XML格式的请求和响应。信息/查询的主要用处是取得或设置公共的用户信息,比如名字,电子邮件,地址等等。其格式为:

我的朋友

2 通信模式的建立

在整个通信过程中涉及到三个角色:客户端、服务器、网络(包括互联网及移动数据网)。客户端可以是移动电话类的手持设备和PC机端的应用程序,在本文中主要是指手机上的应用程序。服务器端包括Dispatch服务器、若干个Jabber服务器、数据库。客户端通过HTTP与服务器端进行数据交换,交换过程中涉及到两个XML流:一个流把数据包从客户端提交到服务器上;另一个流把数据从服务器提交到客户端。当用户想进行通信时,只要启动手机上的客户端程序进行登录,发送一个包括用户登录号和密码的HTTP包给服务器端Dispatch,Dispatch根据用户的登录号和密码到相应的数据库中查询、对比,进行身份验证,若验证成功,给客户端程序返回一个HTTP应答包,在返回的HTTP应答包中包含了分配给该用户的一个Jabber服务器的IP地址和通信的端口号,随后客户端就向指定Jabber服务器发起HTTP连接请求,获得HTTP连接标识,这样就可以利用这个标识进行一系列的通信活动。若服务器端没有通过客户端的身份认证,则会返回给客户端一个错误提示,同时断开与该用户的连接。

3 具体通信过程及客户端实现的效果

3.1 获取Jabber服务器的IP地址和端口号

客户端应用程序首先必须知道自己应该与哪个Jabber服务器进行通信,所以它必须要通过服务器端的Dispatch这个模块来获取与之通信的Jabber服务器的IP地址和端口号。为此它首先得发送一个数据包给Dispatch,Dispatch收到这个包后进行解析,到数据库中进行查询、验证后再回复客户端应用程序。成功的话,返回某个Jabber服务器的IP地址和端口号。在客户端应用程序与服务器端进行联系时都涉及到基于HTTP协议的连接,而HTTP协议是一个请求/响应型的协议,在发送请求时必须同时发送请求所需要的数据。利用HTTP连接发送数据主要有两种方式:GET和POST方式。在GET方式下,发送的数据是被当作URL的一部分被发送到服务器端,这种方式只能传送编码的文本信息,并且传送的数据大小有限制;而在POST方式下,发送的数据被当作数据流的形式单独向服务器发送,这种方式可以传递任意格式的数据(包括二进制格式的数据),并且传送的数据没有大小限制。Sun公司推出的J2ME的CLDC中有专门用于进行网络通信的类库包javax.microedition.io,使用该类库包下定义的HttpConnection类可以实现HTTP连接。当客户端应用程序向服务器发送请求连接的包之后,就可以使用getResponseCode()方法来获得服务器端返回的状态码。通过读取这个状态码,客户端的应用程序就会知道服务器端处理数据的状态,如果服务器端返回的状态码是HttpConnection.HTTP_OK,就表示服务器端处理数据成功,否则服务器端处理数据失败,客户端须得重新发送连接请求。具体情况如下:

1) 客户端向服务器端Dispatch请求与它匹配的Jabber服务器的地址

向服务器端的Dispatch发送一个HTTP包的内容为:

GET /dispatch.xml?Id=9063@pica&Version=0.609.302.cn HTTP/1.1

X-Online-Host: 211.90.198.191:80

User-Agent: Profile/MIDP-1.0 Configuration/CLDC-1.0

User-Agent: UNTRUSTED/1.0

Content-Length: 0

Host: 211.90.198.191:80

由于客户端应用程序只是想要获取与之进行通信的那个Jabber服务器的IP地址和端口号,所以发送的数据量并不是很多,所以采用了GET方法发送只有HTTP包头的数据包就可以了。由这个包我们可以看出Dispatch所在的IP地址是211.90.198.191:80,当它收到这个包时,立即进行解析,获得了该用户的登录号和密码,然后根据该用户的登录号到中心数据库中去查询、验证,决定它与哪个Jabber服务器通信,从这里可以看出,服务器端的Dispatch模块起调度、分配作用,因为随着用户数量的不断增加,一个或几个Jabber服务器显然满足不了需要,必须要随着用户数的增加,随时增加服务器端的Jabber服务器的数目,怎样决定哪些用户与哪个Jabber服务器通信?就由Dispatch模块来决定。

服务器端的Dispatch给该用户返回的包的内容为:

HTTP/1.0 200 OK

Server: jabber/http-0.4

Expires: Fri, 10 Oct 1997 10:10:10 GMT

Pragma: no-cache

Cache-control: private

Connection: close

Content-Type: text/xml

Content-Length: 67

Ip=219.235.1.137

Port=4998

Domain=pica

Resouce=pica

Time=1200

客户端的应用程序按照Jabber XML协议的结构来解析这个包之后,得知自己应与IP地址为219.235.1.137,端口号为4998的Jabber服务器进行通信。于是服务器端的Dispatch模块就不再与客户端的应用程序打交道了。

客户端的发包和收包函数为:

void httpRequest(String page_path) throws Exception{

……………

//发送的HTTP包的包头

hcon=(HttpConnection)Connector.open("http:// 211.90.198.191:80",

Connector.READ_WRITE,true);

hcon.setRequestMethod(HttpConnection.GET);

hcon.setRequestProperty("X-Online-Host","211.90.198.191:80");

hcon.setRequestProperty("User-Agent","Profile/MIDP-1.0 Configuration/CLDC-1.0");

//发送的HTTP包的包体

if(xmlParam!=null){

bytearrayoutputstream=new ByteArrayOutputStream();

dataoutputstream1=new DataOutputStream(bytearrayoutputstream);

dataoutputstream1.writeUTF(xmlParam);

byte abXmlParam[]=bytearrayoutputstream.toByteArray();

hcon.setRequestProperty("Content-Length",""+(abXmlParam.length-2));

dos=hcon.openDataOutputStream();

dos.write(abXmlParam,2,abXmlParam.length-2);

}

///以下为收包的过程

if((hcon.getResponseCode())!=hcon.HTTP_OK)

throw new Exception("invalid response");

int recvs=(int)hcon.getLength();

dis=hcon.openDataInputStream();

if(recvs>0){

rcv_bytes=new byte[(int)hcon.getLength()];

dis.readFully(rcv_bytes);

} else{……}

String sResponse=new String(rcv_bytes,0,recvs>0?recvs:k,"UTF-8");

if(sResponse.length()>0){

reader=new XmlReader(sResponse);

parse(reader,cmdType);}

……………}

2) 客户端应用程序向具体的Jabber服务器发送连接请求:

当客户端应用程序获得了与它相匹配的Jabber服务器的IP地址和端口号时,就可以向该Jabber服务器发送HTTP连接请求。具体的HTTP包的内容为:

GET /login-sid.xml?jid=9063@pica&pass=123456&version=0.609.301.cn HTTP/1.1

X-Online-Host: 219.235.1.137:4998

Content-Type: text/xml

User-Agent: Profile/MIDP-1.0 Configuration/CLDC-1.0

User-Agent: UNTRUSTED/1.0

Content-Length: 0

Host: 219.235.1.137:4998

3) 服务器端向客户端应用程序返回响应包:

服务器返回的HTTP包为:

HTTP/1.0 200 Ok

Content-type: text/xml

Content-length: 60

1973594324

返回来的这个包除了告诉客户端,服务器处理数据成功(OK),同时也返回了客户端与服务器端建立HTTP连接的标识sid,即1973594324。随后的客户端与服务器端进行通信就在这条做了标记的HTTP连接的基础上进行的。

此时的客户端的发包和收包的函数仍然是httpRequest(String page_path),只不过所不同的是此时与之相联系的服务器的IP地址变了。

3.2 与Jabber服务器建立HTTP连接进行通信

从上面可知,当客户端向Jabber服务器发送连接请求后,从服务器那里立即返回一个应答包,获得了这个HTTP连接的标识。这个标识是非常重要的,只有得到这个标识,才能说明客户端应用程序与Jabber服务器建立HTTP连接成功了,于是客户端应用程序就可以通过这个标识与服务器之间可以进行进一步的通信,如取好友列表、取聊天室、发送与接收短文本信息、查找在线好友、通过外部接口服务器与其它即时通信产品(如QQ)进行通信等一系列活动。

如: 客户端利用所获得的HTTP连接标识从Jaber服务器取好友列表情况

向Jabber服务器发送的数据包为:

HTTP包头:

POST /raw.xml?sid=1973594324 HTTP/1.1

X-Online-Host: 219.235.1.137:4998

Content-Type: text/xml

User-Agent: Profile/MIDP-1.0 Configuration/CLDC-1.0

Content-Length: 89

User-Agent: UNTRUSTED/1.0

Host: 219.235.1.137:4998

HTTP包体:

<

/jabber>

由于发送的数据包内容比较多用HTTP的POST方法来传送,分两块:一块是HTTP头,带有上面建立连接时所得到的HTTP会话标识sid=1973594324,向服务器请求获得raw.xml资源,同时还要指明服务器所在的IP地址和端口号等信息;另一块是HTTP包体,这个包体表示你要求的具体内容,上面这个包是要求取好友列表。当服务器接到这个包时,经过解析发现客户端要求取自己的好友列表,立即到数据库中去提取该用户的好友列表以Jabber XML协议的结构形式构造一个数据包发送给该客户端,客户端在收到这个数据包后,按照Jabber XML的协议结构的形式进行解析,把解析所得到的结果在用户的手机界面上显示出来,显示的情况见图2所示。一旦取好友列表成功后,就可以与好友进行聊天,传图片等各项活动了。

3客户端的显示效果

图2为客户端的显示效果。

4 结论

目前随着国内移动网络的逐步成熟,基于移动互联网的应用正在快速增长,不过应用比较多的主要是游戏和移动广告之类的,而应用到即时通信、移动定位、移动电子商务的还为数不多。基于移动互联网的即时通信处在信息、个性化与商务的交汇点,具有传统通信方式无法比拟的优势,用户既可以进行通信,也可以进行交友或从事各种商务活动。当然,如果能够把基于移动互联网的即时通信软件与各种多媒体技术结合起来,开发各种具有视频的通信系统,必将把我国移动互联网技术推到一个新的高度,这也是我们今后的研究方向。

参考文献:

[1] Dreamtech.即时消息传递系统编程源代码解析[M].北京:电子工业出版社,2002.

[2] 卢军.J2ME应用程序开发(手机、PDA程序开发捷径)[M].北京:中国铁道出版社,2002.

[3] 南利平.通信原理简明教程[M].北京:清华大学出版社,2002.