使用 agsXMPP 库创建 Jabber 客户端






4.98/5 (27投票s)
本文描述如何创建一个小的 Jabber 聊天客户端。
引言
我想通过使用 Jabber 协议,深入了解即时消息开发。我首先查看了 The Code Project,但找不到任何关于 Jabber 客户端开发的帖子。因此,在熟悉了这些内容之后,我认为自己有责任写一篇关于如何创建一个小的 Jabber 客户端的文章。
在本文中,我想通过一个简单的示例应用程序介绍 Jabber 开发,该应用程序允许您与您的好友列表中的一位联系人聊天。该示例被写成一个控制台应用程序,但将其代码转移到小型 Windows 应用程序中应该不成问题。
Jabber/XMPP
Jabber 是一种开放的即时消息协议(类似 Skype)。Jabber 的优势在于,它是一种基于 XML 的协议,平台无关,并且可以在多种操作系统下开发客户端。它还提供了与其他即时消息服务(如 ICQ)连接的可能性。Jabber 基于 XMPP 协议(Jabber 的衍生协议),该协议于 2004 年标准化。
一个简化的 Jabber 网络如下所示

本文中使用的最重要 Jabber 术语是
JID: Jabber ID,看起来像电子邮件地址(例如 Test@TestServer.com),其中 *TestServer.com* 是 Jabber 服务器(您可以在 此处找到公共 Jabber 服务器列表)。
在上面的网络中,我们将有以下 JID
Client1@Server1
Client2@Server1
Client3@Server2
Roster: 联系人(朋友、家人)列表。Roster 可以像树一样组织(因为 Jabber 协议是基于 XML 的),带有文件夹和 JID。
一个基于 TCP 的 XMPP 流的基本示例可能如下所示
C: <?xml version='1.0'?>
<stream:stream
to='example.com'
xmlns='jabber:client'
xmlns:stream='http://etherx.jabber.org/streams'
version='1.0'>
S: <?xml version='1.0'?>
<stream:stream
from='example.com'
id='someid'
xmlns='jabber:client'
xmlns:stream='http://etherx.jabber.org/streams'
version='1.0'>
... encryption, authentication, and resource binding ...
C: <message from='juliet@example.com'
to='romeo@example.net'
xml:lang='en'>
C: <body>Art thou not Romeo, and a Montague?</body>
C: </message>
S: <message from='romeo@example.net'
to='juliet@example.com'
xml:lang='en'>
S: <body>Neither, fair saint, if either thee dislike.</body>
S: </message>
C: </stream:stream>
S: </stream:stream>
其中 C
是客户端,S
是服务器。此示例来自 此处。
作为一个开放和标准化的协议,有大量的库适用于不同的编程语言和操作系统。在我寻找 C# 库时,我找到了 agsXMPP
库,它处理最重要任务,如 Jabber 客户端甚至 Jabber 服务器开发。agsXMPP
在两种许可证下提供,即 GPL 用于开源项目,以及商业许可证用于闭源项目。
要开始使用 agsXMPP
库,您可以 此处 下载 SDK。
有关 Jabber/XMPP 的更详细信息,您应该 此处、此处 和 此处 查看。
Jabber 客户端
此示例应用程序只是一个关于如何创建 Jabber 客户端的演示;它不存储任何连接数据,也不提供创建新帐户的功能。因此,如果您想使用该代码开发一个真实世界的客户端,您将需要为代码添加更多功能。
现在我们准备好开发自己的 Jabber 客户端了。在这个示例中,我选择了一个控制台应用程序,因为它使代码更易读。由于 agsXMPP
库提供了大量事件来处理各种功能,这使得控制台应用程序不是首选,我认为 Windows 窗体应用程序乍一看会让人有些困惑。
那么,这个示例应用程序的目标是什么?
- 连接到 Jabber 服务器并验证 Jabber 用户
- 将用户的在线状态发送到服务器
- 处理我们好友列表中的联系人的在线状态(接收所有可用的联系人)
- 最后但并非最不重要的是,聊天功能(发送和接收聊天消息)
那么,让我们开始吧。
参考文献
要在您自己的项目中使用 agsXMPP
,您必须在您的项目中添加对 agsXMPP.dll 的引用。对于此示例,您还应该在文件头添加以下 using
指令
using agsXMPP;
using agsXMPP.protocol.client;
using agsXMPP.Collections;
using agsXMPP.protocol.iq.roster;
using System.Threading;
连接和认证
要连接到 Jabber 服务器,我们需要一个 JID(Jabber ID)和相应的密码。首先,我们必须创建一个新的 JID
对象,并将用户的 JID 作为字符串参数传递。之后,我们可以创建一个新的 XmppClientConnection
对象,并将 JID
对象的服务器属性作为构造函数参数。代码如下所示
Console.WriteLine("Login");
Console.WriteLine();
Console.WriteLine("JID: ");
string JID_Sender = Console.ReadLine();
Console.WriteLine("Password: ");
string Password = Console.ReadLine();
Jid jidSender = new Jid(JID_Sender);
XmppClientConnection xmpp = new XmppClientConnection(jidSender.Server);
现在我们必须打开连接,并等待连接和认证。在 agsXMPP
库中,XmppClientConnection.Open()
方法是异步执行的,因此我们必须注册 OnLogin
事件处理程序,并等待 OnLogin
事件触发。这是 Windows 应用程序的一个很好的解决方案,但它使控制台应用程序不那么理想。代码应该如下所示
xmpp.Open(jidSender.User, Password);
xmpp.OnLogin += new ObjectHandler(xmpp_OnLogin);
我通过一个简单的 do
循环解决了等待 OnLogin
触发的问题,我知道有更优雅的解决方案,但它 just does what it should do
Console.Write("Wait for Login ");
_wait = true;
do
{
Console.Write(".");
i++;
if (i == 10)
_wait = false;
Thread.Sleep(500);
} while (_wait);
现在我们必须看一下 xmpp_OnLogin
方法
static void xmpp_OnLogin(object sender)
{
_wait = false;
Console.WriteLine("Logged In");
}
我们只是等待 OnLogin
事件触发(这意味着我们已登录并经过身份验证),然后退出循环以继续我们的程序。现在我们可以获取有关 XmppClientConnection
对象的连接和身份验证状态的一些信息
Console.WriteLine("xmpp Connection State {0}", xmpp.XmppConnectionState);
Console.WriteLine("xmpp Authenticated? {0}", xmpp.Authenticated);
发送在线状态
为了让我们的好友列表成员看到我们在线,我们必须将我们的在线状态发送到服务器。这项小任务如下
Presence p = new Presence(ShowType.chat, "Online");
p.Type = PresenceType.available;
xmpp.Send(p);
现在他们可以在他们的好友列表中看到我们在线并且可以聊天(此任务对于接收我们好友列表成员的在线状态是必需的)。
接收我们好友列表成员的在线状态
要接收我们好友列表成员的在线状态,我们必须注册 OnPresence
事件处理程序
xmpp.OnPresence += new PresenceHandler(xmpp_OnPresence);
现在我们必须等待事件触发(它现在触发了,如果好友列表成员的在线状态发生变化)。注意:我们只能看到在线状态类型为“可用”的好友列表成员。
static void xmpp_OnPresence(object sender, Presence pres)
{
Console.WriteLine("Available Contacts: ");
Console.WriteLine("mailto:%7B0%7D@%7B1%7D%20%20%7B2%7D">{0}@{1} {2},
pres.From.User,pres.From.Server,pres.Type);
Console.WriteLine();
}
发送和接收消息
现在我们可以开始最有趣的部分:聊天!聊天基本是如何工作的?我们向可用的聊天伙伴发送消息(我们需要他的 JID),并在 MessageCallBack
方法中处理收到的消息。为了准备接收传入消息,我们必须执行以下语句
xmpp.MesagageGrabber.Add(new Jid(JID_Receiver),
new BareJidComparer(), new MessageCB(MessageCallBack), null);
现在,当新消息到达时,将执行 MessageCallBack
方法
static void MessageCallBack
(object sender, agsXMPP.protocol.client.Message msg, object data)
{
if (msg.Body != null)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("{0}>> {1}", msg.From.User, msg.Body);
Console.ForegroundColor = ConsoleColor.Green;
}
}
发送消息是一项相当简单的任务
xmpp.Send(new Message(new Jid(JID_Receiver), MessageType.chat, outMessage));
其中 JID_Receiver
是我们聊天伙伴的 JID
对象。此代码应打包在循环中,以发送多条消息(在下载的示例中,我将其放入了一个 do
循环中,退出条件为字符串 q!
)。完成后,您只需关闭 XmppClientConnection
对象
xmpp.Close();
聊天
这就是创建这样一个小的 Jabber 聊天客户端所需要的一切

我的聊天伙伴使用 PSI 的相应屏幕截图

摘要
agsXMPP
库提供了更多 Jabber/XMPP 功能,例如创建自己的 Jabber 服务器或创建自己的数据包。我认为,对于 C# 下的 Jabber 开发入门来说,最好从客户端开发开始。agsXMPP
SDK 提供了一些非常详细的示例,例如基于 Windows 的迷你客户端和服务器组件。如果您想更深入地研究这项技术,我建议您在深入研究库的源代码之前先学习这些示例。