Archived

This forum has been archived. Please start a new discussion on GitHub.

How to pass a callback object or proxy.

I'm confused about how to go about passing a callback object or proxy from a client to a server and I have searched the forms and the the documentation.

I have the following call back interface in the client which is passed to the server.

interface ClientCallback
{
void signalReport(TcsSignalReport report);
};

interface Payload
{
idempotent void setCallback(
short userId, ClientCallback callback);
}

I would expect the generated server code to receive a ClientCallbackPrx but instead it seems to get a ClientCallBackPtr.

I plan on calling ice_batchOneWay but that fails because that is a method on a Proxy not Object!

PayloadAdapter.cpp:149: error: 'class Tcs::ClientCallback' has no member named 'ice_isBatchOneWay'
PayloadAdapter.cpp:151: error: 'class Tcs::ClientCallback' has no member named 'ice_batchOneway'

void PayloadAdapter::setCallback(
Ice::Short UserId,
const Tcs::ClientCallbackPtr & aCallback)
{
// Create a batch one way proxy.
if ( ! aCallback->ice_isBatchOneWay() )
{
aCallback = aCallback->ice_batchOneway();
}
mCallbackTable[UserId] = aCallback;
}


My questions are 1) how do I turn on batch oneway calls for the callback and 2) why is it a Ptr and not a Prx that is passed to the server?

Thanks

Comments

  • benoit
    benoit Rennes, France
    Hi John,

    You should change your Slice to:
    interface Payload
    {
    idempotent void setCallback(short userId, ClientCallback* callback);
    }
    

    Note the "*" in the ClientCallback parameter. For more information on this, see "4.10.5 Interface Semantics and Proxies" in the Ice manual here. Without the proxy operator, the interface is passed by value (as described here "4.11.11 Pass-by-Value Versus Pass-by-Reference" in the Ice manual).

    You'll also find a callback example in the demo/Ice/callback directory of your Ice distribution.

    Cheers,
    Benoit.
  • matthew
    matthew NL, Canada
    You may also want to read my article Proxies in issue 23 of Connections, http://www.zeroc.com/newsletter/issue23.pdf
  • Demo works but doesn't have ice_isBatchOneWay.

    Thanks, it now generates the Prx I expected (I certainly didn't want to pass the object by value!) however I still get the same compile errors.

    So I tried to modify the demo to add a call to ice_isBatchOneWay() I get the same error().
    void
    CallbackSenderI::initiateCallback(const CallbackReceiverPrx& proxy, const Current& current)
    {
        cout << "initiating callback" << endl;
        try
        {
            if ( proxy->ice_isBatchOneWay() )
                cout << "is not a batch one way\n";
            proxy->callback(current.ctx);
        }
        catch(const Exception& ex)
        {
            cout << ex << endl;
        }
    }
    

    Here's the error I get.

    CallbackSenderI.cpp: In member function `virtual void CallbackSenderI::initiateCallback(const Demo::CallbackReceiverPrx&, const Ice::Current&)':
    CallbackSenderI.cpp:23: error: 'class IceProxy::Demo::CallbackReceiver' has no member named 'ice_isBatchOneWay'
  • dwayne
    dwayne St. John's, Newfoundland
    It should be ice_isBatchOneway(), not ice_isBatchOneWay().
  • Success at last.

    I'm going summarize it then. The variable 'proxy' is const so we need a new variable 'tmpProxy' so that we can assign to it to create the batch oneway.
    void CallbackSenderI::initiateCallback(const CallbackReceiverPrx& proxy, const Current& current)
    {
        CallbackReceiverPrx tmpProxy = proxy;
        try
        {
            if ( ! proxy->ice_batchOneway() )
                tmpProxy = tmpProxy->ice_batchOneway();
            tmpProxy->callback(current.ctx);
        }
        catch(const Exception& ex)
        {
            cout << ex << endl;
        }
    }
    

    Thanks again
  • matthew
    matthew NL, Canada
    Why are you passing back the callers context information?
  • Good catch!
    matthew wrote: »
    Why are you passing back the callers context information?

    That was in the original callback demo I started with. I went back and pulled it out of the Ice-3.3.0.tar.gz file again to make sure I didn't add it.
    proxy->callback(current.ctx);
    

    I won't pass it back in my real code.
  • matthew
    matthew NL, Canada
    You are right, its in the original demo, and I don't think it is necessary. We'll look into why that is being done.