如果您还不知道agsXMPP是什么,您可以先阅读我的这篇随笔:agsXMPP Software Design

agsXMPP致力于创建一个轻量、快速的跨平台类库,用于XMPP协议。

通过下面的三项技术,agsXMPP达到了这个目标。

  1. 异步套接字
  2. 与工厂模式结合的快速XML解析器
  3. 自有的轻量级XML Dom,作为所有agsXMPP协议类的基础

agsXMPP分析:agsXMPP简要指南 (转)我们为什么不直接所用Microsoft的System.Xml命名空间里的类呢?

因为我们决定创建自己的轻量级的Xml Dom,能够飞快地运作,特别是在像PPC's和Smartphones这样的嵌入式设备上。

XmlTextReader有利于SAX-like的解析。但是Microsoft在.NET1.1的SP1中做了下改变,这使得我们不能够再使用它来解析网络流。所以我们需要另外的XML解析器。

类库的惊人之处在哪?

一旦从套接字接收到数据,该数据便由sax-like XML解析器解析。此解析器使用工厂模式来创建agsXMPP协议类相关的元素。

示例:

套接字接收到一条信息,将比特流推送至解析器。XML解析器探测到隶属于jabber:client命名空间中名字为message的开标签符。在元素创建前,解析器在工厂散列表中做个查找。这样就创建了agsXMPP.protocol.client.Message类的一个实例。如果表中不存在name/namespace的绑定,则会创建agsXMPP.Xml.Element的一个实例。

所有的XMPP协议类都派生自agsXMPP.Xml.Element。他们都是在内存中保持XML树的'abstract'元素。所有的属性都是'realtime properties'。在我们要读取消息体,调用消息体属性时,类将会实时查找<body/>元素。

Creating your own packet types

下面的小例子中我们将要创建一个我们自己的扩展,通过XMPP网络发送天气信息。最简单的方法是将天气的数据信息嵌入到一个message节中。嵌入了天气信息的新XML message如下所示:

<message xmlns="jabber:client" to="romeo@montage.net">
    
<weather xmlns="agsoftware:weather">
        
<humidity>90</humidity>
        
<temperature>57</temperature>
    
</weather>
</message>

我们要给这个新的协议创建一个新的命名空间和3个新元素:weather、humidity和temperature

首先,我们给我们定制的XML元素创建一个新的类weather.cs,派生自agsXMPP.Xml.Dom.Element。

agsXMPP分析:agsXMPP简要指南 (转)using System;
agsXMPP分析:agsXMPP简要指南 (转)
using agsXMPP.Xml.Dom;

agsXMPP分析:agsXMPP简要指南 (转)
namespace MiniClient
}

然后在元素工厂中注册这个新类。如果不注册,在解析XML流时XML解析器就不会weather对象。我们通过下面的代码注册该类:

agsXMPP.Factory.ElementFactory.AddElementType("weather",
"agsoftware:weather"typeof(Weather));

我们在使用agsXMPP处理其它事件时,应该先注册我们自己的元素。

现在我们能够创建自己的weather message,然后发送:

Weather weather = new Weather(9057);
Jid to 
= new Jid("romeo@montage.net");
Message msg 
= new Message();
msg.To 
= to;
// Add our weather Element
msg.AddChild(weather);
// Send the message
XmppCon.Send(msg);

接收此message的另一个应用程序可以像OnMessage handler那样访问到我们的定制数据:

private void XmppCon_OnMessage(object sender, Message msg)
{
    
if (msg.HasTag(typeof(Weather)))
    {
        Weather weather 
= msg.SelectSingleElement(typeof(Weather)) as Weather;
        Console.WriteLine(weather.Temperature.ToString());
        Console.WriteLine(weather.Humidity.ToString());
    }
}

现在我们创建了我们第一个自己的(信息)包,包含了一个message节。接下去我们要创建基于Iqs的小型weather service。

service的raw xml protocol:

Romeo向weather service请求了他城市的天气信息,zip code为'74080':

<iq from='romeo@montagne.net' to='weather.mortagne.net' type='get' id='agsXMPP_1'>
    
<query xmlns='agsoftware:weather'>
        
<zip>74080</zip>
    
</query>
</iq>

接着weather service查找该zip code的天气数据,然后返回结果给Romeo:

<iq to='romeo@montagne.net' from='weather.mortagne.net' type='result' id='agsXMPP_1'>
    
<query xmlns='agsoftware:weather'>
        
<humidity>90</humidity >
        
<temperature>57</temperature>
        
<zip>74080</zip>
    
</query>
</iq>

Weather.cs的源代码:

agsXMPP分析:agsXMPP简要指南 (转)using System;
agsXMPP分析:agsXMPP简要指南 (转)
using agsXMPP.Xml;
agsXMPP分析:agsXMPP简要指南 (转)
using agsXMPP.Xml.Dom;
agsXMPP分析:agsXMPP简要指南 (转)
agsXMPP分析:agsXMPP简要指南 (转)
public class Weather : Element
}

WeatherIq.cs的源代码:

agsXMPP分析:agsXMPP简要指南 (转)using System;
agsXMPP分析:agsXMPP简要指南 (转)
using agsXMPP;
agsXMPP分析:agsXMPP简要指南 (转)
using agsXMPP.protocol.client;
agsXMPP分析:agsXMPP简要指南 (转)
agsXMPP分析:agsXMPP简要指南 (转)
public class WeatherIq : IQ
}

当然我们要在工厂里注册Weather对象,使用下面代码:

agsXMPP.Factory.ElementFactory.AddElementType("weather",
"agsoftware:weather"typeof(Weather));

Romeo的客户端使用WeatherIq对象创建了请求Iq包:

WeatherIq wIq = new WeatherIq(IqType.get);
wIq.To 
= new Jid("weather.mortagne.net");
wIq.From 
= new Jid("romeo@montagne.net");
wIq.Query.zip 
= 74080;
// Send the message
XmppCon.Send(wIq);

weather service在Iq handler中接收此请求,然后把响应发回给Romeo。在weather service中获得请求信息,然后编辑:

agsXMPP分析:agsXMPP简要指南 (转)private void XmppCon_OnIq(object sender, agsXMPP.Xml.Dom.Node e)
}

Romeo接收到响应,然后通过我们的weather对象的属性访问到天气数据。

相关文章:

  • 2021-08-15
  • 2021-07-23
  • 2021-11-20
  • 2021-10-29
  • 2022-12-23
  • 2022-12-23
  • 2021-06-16
猜你喜欢
  • 2022-01-03
  • 2022-12-23
  • 2021-07-29
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案