尽管我们仅仅知道
Jabber
协议工作的基本原理,但这已经足够让我们在站在更高的层次上来理解
Jabber
通讯会话。理解一个
Jabber
协议的最好办法是看看怎么在网络中穿行的。
Jabber
的
xml-based
包简单的格式化一个原始的
jabber
数据。不同的规定以来与二进制数据,
xml
使用简单,标记文本是熟悉的
Html
。你不需要另外解码就可以给所有人识别,对外发数据也不需要任何工具。我们可以手动的用一般的
teltel
工具连接任何
jabber
服务器,读取原始的
XML
,用一般的键盘键入。在此,我们有详细的解释。
开始,你启动你的
Telnet
程序。在一些平台,你的
telnet
程序可以是一个好看的可视程序启动。不管怎样,每一个我知道的操作系统,不管
window
还是
Unix
和
MacosX
,都可以用
telnet
服务端口。你必须充实你的服务器和端口。例如你可以用开放的
shigeoka.com
服务:
telnet shigeoka.com 5222.
telnet
程序在做这些之后将得到一些公开的应答信息。
在这个示例中,我们将看到一个简单的
jabber
验证和消息的发送的练习。对于发送和接受信息,我们将用两个人客户端会话,记录两个不同的客户账户。记录如下:
lain smirk
1、
链接
jabber
服务
shigeoka.com
2、
打开
jabber
流
3、
在
shigeoka.com
创建一个用户
iain,
密码是
secret
4、
在
shigeoka.com
服务器验证用户
iain,
密码
secret
5、
链接
jabber
服务
shigeoka.com
6、
打开
jabber
流
7、
在
jabber.org
创建一个用户
smirk,
密码
secret
8、
验证用户
smirk
9、
发送一个信息到用户
smirk
10、
更新
available
的出席状态
11、
更新出席状态到
available
12、
从
iain
回复信息
13、
发送信息到
iain
14、
接受阿里子
smirk
的信息
15、
关闭流
16、
关闭流
第一步链接
jabber
服务器用
telnet
:
“
初始
” telnet
屏幕
发生了什么
% telnet shigeoka.com 5222
开启
telnet
连接服务器
.
Trying shigeoka.com... Telnet
应用的信息
Connected to shigeoka.com.
额外文本可以改变
Escape character is '^]'.
与服务器对话的开始,我们需要开启一个
jabber xml
流。
<stream>
元素定义在
http://etherx.jabber.org/streams命名空间
,必须总是一个正确的
jabber
流。我们也用到
client/server
协议,因此我们必须定义
jabber
:
client
默认的命名空间。另外,为支持虚拟
jabber
服务,开放的
<stream>
标签需要包含一个我们希望链接的服务器的名字的属性。
“
初始
” telnet
屏幕
发生了什么
<?xml version='1.0'?> XML
版本
(
可选
).
<stream:stream
未关闭的
stream
元素
.
xmlns:stream=
'http://etherx.jabber.org/streams'
<stream>
命名空间
xmlns='jabber:client' <stream>
默认命名空间
.
to='shigeoka.com'>
告诉服务器连接的域名
<?xml version='1.0'?> XML
版本
(
可选
)
<stream:stream
未关闭的
stream
元素
.
xmlns:stream=
'http://etherx.jabber.org/streams'
<stream>
命名空间
id='3C0FB738'
这个连接随机的
“session ID” xmlns='jabber:client' <stream>
默认命名空间
from='shigeoka.com'>
告诉客户端连接的来源
一旦确立了会话,我们就可以创建一个用户。在许多时候,你的帐户一名存在于服务器中。实际上,只要打开
jabber
服务例如
jabber.org
就能允许你建立一个用户。如果你已经拥有了一个帐户那你可以跳过这一步。
“
初始
” telnet
屏幕
发生了什么
<iq type='set' Account registration is an IQ set protocol.
id='reg_id'> We use a unique ID to track this query.
<query xmlns='jabber:iq:register'> jabber:iq:register IQ extension protocol.
<username>iain</username> The user name for the account.
<password>secret</password> The password for the account.
</query>
</iq>
<iq type='result' Empty result indicates success.
id='reg_id'/> Match queries and results using ID.
现在,我们拥有了一个用户帐户。我们能够用
jabber:iq:authIQ
扩展协议验证它。在这里,我们将用到简单的
Plain authentication
协议。
Step 4:
服务器验证
“
初始
” telnet
屏幕
发生了什么
<iq type='set'
验证是一个
IQ set
类型协议
.
id='auth_id'>
我们用
unique ID
跟踪这个查询
.
<query
xmlns='jabber:iq:auth'>
这是一个
jabber:iq:auth IQ
扩展协议
.
<username>iain</username>
帐户的用户名
<password>secret</password>
密码
<resource>test</resource>
这个客户的
resource
</query>
</iq>
<iq type='result'
结果为空表示成功
.
id='auth_id'/> packet ID
高屋我们
IQ
查询时成功的
.
这是不是相当容易?现在我们重复同样的步骤在第二个
telnet
窗口,因为我们有两个
jabber
会话记录在
iain
和
smirk
帐户之间。
Step 5-8: The “smirk” client authenticating with the server
“
初始
” telnet
屏幕
发生了什么
<password>secret</password> The password for the account.
<resource>test</resource> The resource for this client.
</query>
</iq>
<iq type='result' Empty result indicates success.
id='auth_id'/> The packet ID tells us what IQ query was successful.
“Raw” smirk client session
% telnet shigeoka.com 5222
Trying shigeoka.com...
Connected to shigeoka.com.
Escape character is '^]'.
<?xml version='1.0'?>
<stream:stream xmlns:stream='http://etherx.jabber.org/streams'
xmlns='jabber:client'
to='shigeoka.com'>
<?xml version='1.0'?>
<stream:stream xmlns:stream='http://etherx.jabber.org/streams'
id='3C0FB73C'
xmlns='jabber:client'from='shigeoka.com'>
<iq type='set'>
<query xmlns='jabber:iq:register'>
<username>smirk</username>
<password>secret</password>
</query>
</iq>
<iq type='result'/>
<iq type='set'>
<query xmlns='jabber:iq:auth'>
<username>smirk</username>
<password>secret</password>
<resource>work</resource>
</query>
</iq>
<iq type='result'
id='pthsock_client_auth_ID'/>
现在我们验证了用户,能够发送消息。我们能够用
iain
客户端发送一个消息到
smirk
。
Step 9: The “iain” client sends a message to the “smirk” client
from='shigeoka.com'>
<iq type='set'>
<query xmlns='jabber:iq:register'>
<username>smirk</username>
<password>secret</password>
</query>
</iq>
<iq type='result'/>
<iq type='set'>
<query xmlns='jabber:iq:auth'>
<username>smirk</username>
<password>secret</password>
<resource>work</resource>
</query>
</iq>
<iq type='result'
id='pthsock_client_auth_ID'/>
我们所做的都是顺势信息,因此我们希望消息立即到达
smirk
客户端。
看看
smirk
客户端会话。消息是否已交付?应该没有消息。消息没有被交付,为什么呢?
回答是
jabber
的出席。回想如果客户可以接受消息,必须能够被服务器感知。当一个客户首次登陆,会话的出席状态设置成
unavailable
。我们必须设置我们的感知状态为
available
以便接受消息。我们更新我们的出席状态到
available
:
Step 10: The “iain” client updates its presence status to available
“
初始
” telnet
屏幕
发生了什么
<presence type='available'/> Presence update.
<message from='shigeoka.com' Server message.
to='iain@shigeoka.com'> Addressed to “iain” client.
<subject>Welcome!</subject> The message’s “subject.”
<body>Welcome to Jabber! </body> The message’s “body.”
<x xmlns='jabber:x:delay' Optional server delay “X extension.”
from='iain@shigeoka.com' Indicates account where message delayed.
stamp='20011206T18:22:09'> The time the message was sent/received.
Offline Storage Message explaining the delay.
</x>
</message>
然后我们的
iain
客户端变成
available
,服务端交付消息到客户端。这个消息来自服务端,并显示为欢迎消息。在客户登录之后,
Jabber
服务经常发送一个消息给用户更新他的最新信息或者服务器状态。这是以特可选项,因此服务器可以不发送。
特殊的消息示例也显示
jabber:X:delay
扩展。这是一个附加的包,服务器和客户端知道消息延迟。在这种情况下,服务器交付消息的同时进行验证。然而,消息不能被交付是因为客户是
unavailable.delayX
扩展不是必须的
jabber
协议特征,因此你的
jabber
服务可以不包含这些消息延迟的包。
选择你的
smirk
客户端
telnet
会话。注意没有任何改变。他的感知仍然是
unavailable
。下面的过程我们仅仅在
iain
客户端会话。然而,让我们用一个快捷方式。
<presence>
包默认的类型是
unavailbale
因此我们不能忽略保存贷款。这些动作做如下:
“
初始
” telnet
屏幕
发生了什么
<presence/> Presence update (available is default).
<message from=' shigeoka.com' Server message.
to=’smirk@shigeoka.com'> Addressed to “smirk” client.
<subject>Welcome!</subject> The message’s “subject.”
<body>Welcome to Jabber! </body> The message’s “body.”
<x xmlns='jabber:x:delay' Optional server delay “X extension.”
from='smirk@shigeoka.com' Indicates the account message delayed at…
stamp='20011206T18:22:38'> The time the message was sent/received.
Offline Storage Message explaining the delay.
</x>
</message>
<message to='smirk@shigeoka.com' Message to “smirk.”
from='iain@shigeoka.com/test'> from iain’s “test” resource.
<subject>Hello</subject> The message’s “subject.”
<body>message text.</body> The message’s “body.”
<x xmlns='jabber:x:delay' Optional server delay “X extension.”
from='smirk@shigeoka.com' Indicates the account message delayed at…
stamp='20011206T18:23:54'> The time the message was sent/received.
Offline Storage Message explaining the delay.
</x>
</message>
如我们所期待的,一旦
smirk
客户变成
available
,我们如愿的接受的消息。在此,服务器欢迎消息,我们发送消息从
iain
到
smik
在第九步。在来一次,服务器附加一个
delay X
扩展的消息。你的服务不能做这些。
回头看
iain
会话。没有新的包出现。如你所能见到,不管
message
还是
presence
协议都有一个服务回复。
IQ
协议在在其他方面为每一请求发送回复。假定一个
<message>
或
<presence>
包从客户发送到服务器,服务器保证它的交付。没有回复以为这成功。失败将被服务发送一个错误包到发送者手里。
当客户端编程
available
,终于得到了消息。然而,因为这是一个实时的因此我们看看但我们发送一个消息到其他可用的用户时发生的事情。我们将用
smirk
会话发送一个消息到
iain
:
“
初始
” telnet
屏幕
发生了什么
<message to='iain@localhost'> A new message to “iain.”
<body>I love messages</body> The message’s “body.”
</message>
当你发送信息,我们不能期望从一个回复的
Message
包得到什么。然而,如果你看到
iain
会话,你将立即看到如下包:
“Raw” iain client session What is happening
<message to='iain@shigeoka.com' A new message to “iain.”
from='smirk@localhost/test' The sender is “smirk” on resource “test.”
<body>I love messages</body> The message’s “body.”
</message>
注意这些包缺乏
delayX
扩展因为没有服务延迟这些消息。你能够随便的在两个会话中发送消息。当你完成之后关闭在
iain
和
smirk
会话中的流。一旦关闭,服务将自动关闭
telnet
连接。如下:
“Raw” client session What is happening
</stream:stream> Close the stream.
Connection closed by foreign host. Telnet application information: server has closed
connection.
% Command prompt.
尽管我们对
jabber
协议没有一个更加详细的了解,当时我么农业对
jabber
协议和不同的
jabber
包有了一个很好的概念。