[jdev] nonblocking RPCCall() in Net::Jabber, can it work?
Scott Bolte
listS+jabber-jdev at niss.com
Mon Mar 15 09:58:05 CST 2004
Thanks for the information Ryan.
I am using RPCCall with mode => 'nonblock'. It has to be
non-blocking since the remote 'user' may be offline when I
make the call.
Like I said, I'm new to jabber, but it looks like SendWithID
does register the ID and packet table. The code path from
RPCCall will include the following line:
$self->RegisterID($object->GetTag(),$id);
I haven't tested it, but I'll speculate RPCCall should
return [$iq->GetTag(), $id] instead of ($id). That would
allow CheckID to be used minutes/hours/days later. The
other solution is to drop the reference to CheckID from
the Modes section of the Net::Jabber::Protocol man page
and point people to XPath for both nonblock and passthru.
I'll add XPath callbacks to my list of things to learn.
In any case, I think I see trouble ahead. The generated id
does not seem unique over time. Therefore replies that comes
to a client's successor, even a successor that shares the
same JID, may be ambiguous. Is that correct?
Btw, it was the persistence of messages that I did not
realize jabber had until last week. (I know, it's an obvious
requirement in light of offline messaging, but I know more
now.) Persistence is the reason I'm switching over to Jabber.
But I now realize there is a critical question I need to
ask... will a session manager (e.g. jabberd 2) store both
IQ and Messages packets or just Messages?
Scott
Ryan Eatmon wrote:
>
> First, are you using the new mode=>'nonblock' argument to the RPCCall
> function? This causes RPCCall (and several other functions) to return
> the id that the packet was sent with.
>
> In this case it just calls SendWithID which does NOT register the id and
> packet tag in the id table. So CheckID() will not return anything
> because it was never registered.
>
> The idea behind this method of operations is that you would register an
> XPath callback on that id that would call a function of your devising
> to handle just the return packet call.
>
> $client->SetXPathCallBacks("/iq[\@id='$id']"=>&yourFunction);
>
> yourFunction would then call RPCParse to get back a data structure for
> the return value.
>
> This *should* be as close to nonblocking as we can get. Your code will
> return to the Process() loop and let you do whatever while waiting for
> the return. Since you know what was going on at the time the RPC call
> was sent, you can tie that state information in a hash with the id
> returned from RPCCall as the key. Then you can look up the state
> information in yourFunction.
>
> One caveat. If this is a long running program. Make sure you
> unregister the XPath callback in your function since the id will never
> be recycled.
>
> $client->SetXPathCallBacks("/iq[\@id='$id']"=>undef);
>
> Hope this helps.
>
>
> Scott Bolte wrote:
> > As far as I can tell, it is not possible to use CheckID() to
> > retrieve the answer to a non-blocking RPCCall() call.
> >
> > CheckID() requires an object tag and an id. Unfortunately,
> > RPCCall() returns just an id. The iq object it creates goes out
> > of scope, taking the tag with it, when RPCCall() returns.
> >
> > I've only been using Jabber for two days so I suspect I'm
> > missing something. Is there any way to do non-blocking RPC and
> > later retrieve the answer packet?
> >
> > Scott
> >
> > P.S. I am using version 1.29 of Net::Jabber.
>
> --
> Ryan Eatmon
> reatmon at jabber.org
>
> _______________________________________________
> jdev mailing list
> jdev at jabber.org
> https://jabberstudio.org/mailman/listinfo/jdev
More information about the JDev
mailing list