kami13sep / jabber-net

Automatically exported from code.google.com/p/jabber-net
Other
0 stars 0 forks source link

RosterManager missing InvokeControl #21

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?
Setup a jabber client and set it's InvokeControl to the proper form.  Now 
create an associated 
roster manager, and set it's Client to the jabber client.  Add a delegate for 
OnSubscription.  
Notice that it get's called in a background thread.

What is the expected output? What do you see instead?
Since the RosterManager class is dependent on a JabberClient, one might expect 
it to follow the 
configuration from the JabberClient.  Or provide it's own InvokeControl.

What version of the product are you using? On what operating system?
1.0.1 on Windows Vista.

Please provide any additional information below.
Also very confused about "jabber.client.RosterManager.Client is obsolete: Use 
the stream 
property instead".  Why?  How do I get the stream from the client?

Original issue reported on code.google.com by robbieha...@gmail.com on 7 Apr 2008 at 5:41

GoogleCodeExporter commented 8 years ago
You may ignore my question about the stream property.  I had not realized that 
JabberClient extends 
XmppStream.

Original comment by robbieha...@gmail.com on 8 Apr 2008 at 3:04

GoogleCodeExporter commented 8 years ago
There are 2 solutions to this problem.

Temporary solution (workaround):
In the client code (outside jabber-net library), simply check for 
InvokeRequired and perform invoke if 
necessary.
Pseudocode:
private void jabberClient_ OnSubscription(RosterManager manager, Item ri, 
Presence pres)
{
    ISynchronizeInvoke invoker = jabberClient.InvokeControl;
    if(invoker != null && invoker.InvokeRequired)
        invoker.Invoke(new SubscriptionHandler(jabberClient_ OnSubscription), new object[] { manager, ri, pres});
    else
        { // Do normal stuff here including GUI updates }
}

Permanent solution:
Basically copy and paste 2 methods from XmppStream (CheckedInvoke and 
InvokeRequired) to the StreamComponent class.  Alter these methods to use 
m_Stream.InvokeControl.  Then use the standard coding 
style from XmppStream for invoking callback methods.  I.e:
if (InvokeRequired)
    CheckedInvoke(OnSomething, new object[] { this, arg});
else
    OnSomething(this, arg);

Original comment by robbieha...@gmail.com on 8 Apr 2008 at 4:10

GoogleCodeExporter commented 8 years ago
I believe this also applies to PresenceManager.

Original comment by robbieha...@gmail.com on 8 Apr 2008 at 4:11

GoogleCodeExporter commented 8 years ago
I really don't see how this is happening.  Are you absolutely certain you have 
an
InvokeControl set on your JabberClient instance?  

I set up a test by using the Example client, logging in to user alice.  From 
another
client, logged in as user bob, send subscribe to alice.  Bob was not on alice's
roster to begin with.

Here's what Alice's client sees on my box:
- Presence type=subscribe comes in to JabberClient.OnElement.
- It's a presence, so we do a CheckedInvoke on OnPresence
- RosterManager.cli_OnPresence is executed on the GUI thread of the 
InvokeControl
- If OnSubscription is set we call it.  Still on the GUI thread, no need to 
Invoke.

If we really need to do an invoke, I'll make XmppStream.CheckedInvoke and
InvokeRequired public, rather than copying code.

Original comment by hil...@gmail.com on 9 Apr 2008 at 5:06

GoogleCodeExporter commented 8 years ago
Wow. I'm an idiot.  You're absolutely right.  I had set the InvokeControl in a 
construtor, and it was still null.  Then 
I didn't notice because I had made thread-safe code in other places outside the 
jabberClient callbacks.

Please ignore/delete this entire issue.

Original comment by robbieha...@gmail.com on 9 Apr 2008 at 9:00

GoogleCodeExporter commented 8 years ago
Wow, that's a relief.  Thank you for all of the good work trying to track this 
down,
though.

Original comment by hil...@gmail.com on 9 Apr 2008 at 11:19