Hi.
We have a Jabber-esque client server package that uses XMPP for
communication over network sockets.
Using .NET 2.0, I need to read a full stanza (i.e. balanced xml) as
soon as available and return it as a string.
So, I've taken my NetworkStream and wrapped an XmlTextReader around it.
At first I tried using ReadOuterXml() to grab the full stanza. This
worked fine except that it blocks until there is more data in the
stream behind the full stanza (since the ReadOuterXml() positions the
stream curser on the next element after the end element of the stanza).
This meant that the last message in would sit there until a new one
arrived...and this is not useful behaviour.
After some experimenting, I found that if I did a Read() on the start
element and then a ReadSubtree(), I could then do a ReadOuterXml() on
the subtrees reader and it returned the full stanza. The Read() blocks
until there is a new message, and the ReadSubtree() blocks until there
is a full stanza available.
However, the problem I've run into is that the ReadOuterXml() on the
subtree will block too, very occasionally (maybe .01% of the time, but
anything greater than 0% is unusable).
Is there a bug in ReadOuterXml()? Is there any other way (short of
writing my own parser) to grab full stanzas as strings?
Here is some sample code (C#) :
MyClass() {
static void Main(string[] args) {
TcpClient client = new TcpClient("hostname", port_no);
NetworkStream stream = client.GetStream();
StreamReader sIn = new StreamReader(stream, new
System.Text.UTF8Enconding(false));
XmlTextReader xIn = new XmlTextReader(sIn);
while (true) {
String stanza = xIn.ReadOuterXml(); // this blocks till
data following stanza
}
}
}
or then replace the "while" block in the above with this
xIn.Read();
while (true) {
if (xIn.IsStartElement()) {
XmlReader inner = xIn.ReadSubtree();
inner.Read();
String stanza = inner.ReadOuterXml(); // this
sometimes (< .01%) blocks
inner.Close();
xIn.Read();
} else
xIn.Read();
}
Does anyone have any insights?
Thanks,
Greg