Not logged in. · Lost password · Register
Forum: MatriX and XmppDotNet RSS
Avatar
zbang.yaniv #1
Member since Mar 2011 · 29 posts
Group memberships: Members
Show profile · Link to this post
Subject: NullReferenceExcpetion on IqFilter.SendIq (.net 3.5 client profile)
I have the following method:

private void RequestVcardAsync(Jid to)
        {
            if (m_JidPhotoMapping.ContainsKey(to.Bare))
            {
                return;
            }

            var vcard = new VcardIq(to)
            {
                Type = Matrix.Xmpp.IqType.get
            };

            if (vcard.Id == null)
            {
                vcard.GenerateId();
            }

            m_XmppClient.IqFilter.SendIq(vcard, VcardHandlder);
        }

Sometimes I get this NullReferenceException (I think only when I request MY own vcard):

   at System.Xml.Linq.ElementWriter.WriteElement(XElement e)
   at System.Xml.Linq.XElement.WriteTo(XmlWriter writer)
   at System.Xml.Linq.XNode.GetXmlString(SaveOptions o)
   at System.Xml.Linq.XNode.ToString(SaveOptions options)
   at Matrix.Xml.XmppXElement.ToString(Boolean indented)
   at Matrix.XmppStream.Send(XmppXElement el)
   at Matrix.Xmpp.Client.XmppClient.Send(XmppXElement el)
   at Matrix.IqFilter.SendIq(Iq iq, EventHandler`1 callback, Object state)
   at Matrix.IqFilter.SendIq(Iq iq, EventHandler`1 cb)

The xml looks like this:

<iq id="MX_10" to="-100001271633341@chat.facebook.com/MatriX_adb117ab_4AB9FD9D449F9" type="get" xmlns="jabber:client">
  <vCard xmlns="vcard-temp" />
</iq>

What is the cause for this? Is there another way to get MY vcard photo?
Avatar
Alex #2
Member since Feb 2003 · 4449 posts · Location: Germany
Group memberships: Administrators, Members
Show profile · Link to this post
Quote by zbang.yaniv:
<iq id="MX_10" to="-100001271633341@chat.facebook.com/MatriX_adb117ab_4AB9FD9D449F9" type="get" xmlns="jabber:client">
  <vCard xmlns="vcard-temp" />
</iq>

you are using a full Jid here. You must request the vcard over a bare Jid (without resource).
But this should not cause a NullReferenceException. Maybe your callback does, because you get an empty result or an error response instead of a vcard.

Alex
Avatar
zbang.yaniv #3
Member since Mar 2011 · 29 posts
Group memberships: Members
Show profile · Link to this post
I use the bare now.

Still, sometimes, I receive the NullReferenceException, when I ask for MY facebook vcard.
The callback works alright for other contacts, and does not reach the callback in that case.

<iq id="MX_11" to="-100001271633341@chat.facebook.com" type="get" xmlns="jabber:client">
  <vCard xmlns="vcard-temp" />
</iq>

Is there other way that I should ask for my own vcard (I need the photo)?
Avatar
Alex #4
Member since Feb 2003 · 4449 posts · Location: Germany
Group memberships: Administrators, Members
Show profile · Link to this post
Quote by zbang.yaniv:
Is there other way that I should ask for my own vcard (I need the photo)?

no there isn't. Please post a full stacktrace of your exception.
Avatar
zbang.yaniv #5
Member since Mar 2011 · 29 posts
Group memberships: Members
Show profile · Link to this post
   at System.Xml.Linq.ElementWriter.WriteElement(XElement e)
   at System.Xml.Linq.XElement.WriteTo(XmlWriter writer)
   at System.Xml.Linq.XNode.GetXmlString(SaveOptions o)
   at System.Xml.Linq.XNode.ToString(SaveOptions options)
   at Matrix.Xml.XmppXElement.ToString(Boolean indented)
   at Matrix.XmppStream.Send(XmppXElement el)
   at Matrix.Xmpp.Client.XmppClient.Send(XmppXElement el)
   at Matrix.IqFilter.SendIq(Iq iq, EventHandler`1 callback, Object state)
   at Matrix.IqFilter.SendIq(Iq iq, EventHandler`1 cb)
Avatar
Alex #6
Member since Feb 2003 · 4449 posts · Location: Germany
Group memberships: Administrators, Members
Show profile · Link to this post
this is not a full stacktrace
Avatar
zbang.yaniv #7
Member since Mar 2011 · 29 posts
Group memberships: Members
Show profile · Link to this post
That's what I've got, it that what you mean?

   at System.Xml.Linq.ElementWriter.WriteElement(XElement e)
   at System.Xml.Linq.XElement.WriteTo(XmlWriter writer)
   at System.Xml.Linq.XNode.GetXmlString(SaveOptions o)
   at System.Xml.Linq.XNode.ToString(SaveOptions options)
   at Matrix.Xml.XmppXElement.ToString(Boolean indented)
   at Matrix.XmppStream.Send(XmppXElement el)
   at Matrix.Xmpp.Client.XmppClient.Send(XmppXElement el)
   at Matrix.IqFilter.SendIq(Iq iq, EventHandler`1 callback, Object state)
   at Matrix.IqFilter.SendIq(Iq iq, EventHandler`1 cb)
   at Zbang.API.Chat.BaseChatController.RequestVcardAsync(Jid to) in C:\Zbang\w2_NEW\Zbang.API\Chat\BaseChatController.cs:line 108
Avatar
Alex #8
Member since Feb 2003 · 4449 posts · Location: Germany
Group memberships: Administrators, Members
Show profile · Link to this post
no, there must be more info about which object gets a NullReferenceException.

  1. private void RequestVcardAsync(Jid to)
  2. {
  3.    // when  the to Jid is not null then norhing can cause a NullReferenceException in MatriX here
  4.    if (m_JidPhotoMapping.ContainsKey(to.Bare))
  5.    {
  6.       return;
  7.    }
  8.  
  9.    // nothing can cause a NullReferenceException in this block
  10.    var vcard = new VcardIq(to)
  11.    {
  12.       Type = Matrix.Xmpp.IqType.get
  13.    };
  14.  
  15.    // vcard.Id is never null, because GenerateId is called inside the VcardIq constructor
  16.    if (vcard.Id == null)
  17.    {
  18.       vcard.GenerateId();
  19.    }
  20.  
  21.    // when you are still properly connected to teh XMPP server then I see also no reason why this can cause a NullReferenceException
  22.    m_XmppClient.IqFilter.SendIq(vcard, VcardHandlder);
  23. }

Look also if there is a InnerException object in your exception
Avatar
zbang.yaniv #9
Member since Mar 2011 · 29 posts
Group memberships: Members
Show profile · Link to this post
No InnerException, jid is not null, and is full with correct data.

Now I got ArgumentOutOfRangeException {"Length cannot be less than zero.\r\nParameter name: length"}:
   at System.String.InternalSubStringWithChecks(Int32 startIndex, Int32 length, Boolean fAlwaysCopy)
   at System.String.Substring(Int32 startIndex, Int32 length)
   at Matrix.XmppStream.Send(XmppXElement el)
   at Matrix.Xmpp.Client.XmppClient.Send(XmppXElement el)
   at Matrix.IqFilter.SendIq(Iq iq, EventHandler`1 callback, Object state)
   at Matrix.IqFilter.SendIq(Iq iq, EventHandler`1 cb)
   at Zbang.API.Chat.BaseChatController.RequestVcardAsync(Jid to) in C:\Zbang\w2_NEW\Zbang.API\Chat\BaseChatController.cs:line 108

1) Is there any precondition that must be met?
2) I invoke this method for 'me' in the OnBind event. Perhaps this is a wrong place?
3) Maybe this happens when having a few threads, each running its own XMPP client instance, but the requests happen simultaneously?
Avatar
Alex #10
Member since Feb 2003 · 4449 posts · Location: Germany
Group memberships: Administrators, Members
Show profile · Link to this post
Quote by zbang.yaniv:
1) Is there any precondition that must be met?
no

Quote by zbang.yaniv:
2) I invoke this method for 'me' in the OnBind event. Perhaps this is a wrong place?
It would be better to wait until you get the first OnPresence event. Do you send only one request in the OnBind event, or do you send out the request for your complete roster?

Quote by zbang.yaniv:
3) Maybe this happens when having a few threads, each running its own XMPP client instance, but the requests happen simultaneously?
This can be a problem because your RequestVcardAsync method is not synchronized. You should make sure that only one thread is inside this block using locks or something similar.
Multiple XmppClient objects are no problem, because each client has it own socket and instances inside of MatriX.
Avatar
zbang.yaniv #11
Member since Mar 2011 · 29 posts
Group memberships: Members
Show profile · Link to this post
2) I send vcard request upon OnRosterItem event (so to get all buddies photos)
    Do you mean I can get for the entire buddies in a single call (complete roster? how exactly?)

3) I think that since RequestVcardAsync is called upon each OnRosterItem, it's therefore synchronized by design rather than by locking

The entire purpose of these calls is to get my and all my buddies photos

Thanks for your help!
Avatar
Alex #12
Member since Feb 2003 · 4449 posts · Location: Germany
Group memberships: Administrators, Members
Show profile · Link to this post
Quote by zbang.yaniv:
2) I send vcard request upon OnRosterItem event (so to get all buddies photos)
    Do you mean I can get for the entire buddies in a single call (complete roster? how exactly?)

no you can't

Quote by zbang.yaniv:
3) I think that since RequestVcardAsync is called upon each OnRosterItem, it's therefore synchronized by design rather than by locking
The entire purpose of these calls is to get my and all my buddies photos

MatriX receives the complete roster in one stanza and then creates a single OnRosterItem event for each contact in this stanza.


Depending on the size of your roster its not a good idea to request the vcard of each contact n the OnRosterItem event. When you have 500 contacts then you flood the server with 500 requests.
Its also not good to do this on each login when the photo did not change for the most of your contacts.

I would request only 1-3 Vcards at the same time. In your result callback then request the next one, until you send all requests. In the presence you normally get a hash of the vcard photo. You have to cache the hash also between sessions, and only request the vcard again when the hash changed.

Alex
Close Smaller – Larger + Reply to this post:
Verification code: VeriCode Please enter the word from the image into the text field below. (Type the letters only, lower case is okay.)
Smileys: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Special characters: