Archived

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

Ice Server

Hi,
this is my very simple c++ code for a Ice Server (VC6):

#include <Ice/Ice.h>
#include "output.h"
#include "OutputReceiverI.h"
using namespace std;

int main(int argc, char* argv[])
{
int status = EXIT_SUCCESS;
Ice::CommunicatorPtr communicator;
char output_end_point[20];
try
{
argc = 0;
communicator = Ice::initialize(argc, 0);
strcpy(output_end_point,"tcp -p ");
strcat(output_end_point,"10001");
Ice::ObjectAdapterPtr adapter = communicator->createObjectAdapterWithEndpoints("OutputReceiver", output_end_point);
adapter->add(new OutputReceiverI, Ice::stringToIdentity("OutputReceiver"));
adapter->activate();
communicator->waitForShutdown();
}

catch(const Ice::Exception& ex)
{
cerr << ex << endl;
status = EXIT_FAILURE;
}
if(communicator)
{
try
{
communicator->destroy();
}
catch(const Ice::Exception& ex)
{
cerr << ex << endl;
status = EXIT_FAILURE;
}
}
return status;
}

The files output.cpp and output.h are generated by tho following output.ice file:

#ifndef EXODUS
#define EXODUS

module OutputServer
{

struct AnalogOutput
{
long id; // questo è id del tag dalla tabella tags del DB
float value; // valore della misura da impostare
};

struct DigitalOutput
{
long id; // questo è id del tag dalla tabella tags del DB
int value; // valore della misura da impostare
};


interface OutputReceiver
{
void writeDigital(DigitalOutput item);
void writeAnalog(AnalogOutput item);
};
};

#endif

This is the file OutputReceiverI.h:

#ifndef OUTPUT_I_H
#define OUTPUT_I_H

#include "output.h"

class OutputReceiverI : public OutputServer::OutputReceiver
{
public:

virtual void writeDigital(const ::OutputServer::DigitalOutput&,const Ice::Current&);
virtual void writeAnalog (const ::OutputServer::AnalogOutput&,const Ice::Current&);
};

#endif

This is the file OutputReceiverI.cpp:

#include "OutputReceiverI.h"
#include <Ice/Ice.h>
#include <stdio.h>
#include <stdlib.h>

using namespace std;

void
OutputReceiverI::writeDigital(const ::OutputServer::DigitalOutput& DO,const Ice::Current&){

cout << "ricevo ordine scrittura digitale id=" << DO.id << " valore=" << DO.value << endl;

}

void
OutputReceiverI::writeAnalog (const ::OutputServer::AnalogOutput& AO,const Ice::Current&){

cout << "ricevo ordine scrittura analogico id=" << AO.id << " valore=" << AO.value << endl;

}

The program works properly alone, but when I put the same files in another MFC project I can compile link and run, but the ice clients does not communicate with the server.

Perhaps I can't use the function
communicator = Ice::initialize(argc, 0);
in no console applications??

thanks

rogiov

Comments

  • benoit
    benoit Rennes, France
    Hi,

    It's fine to call Ice::initialize(argc, 0) with argc = 0 but you could also just call Ice::initialize() instead. Did you try the demo/Ice/MFC demo provided with your Ice distribution? Perhaps it can help figuring out the problem with your application.

    If you need further help with this issue, we would need to know which Ice version you're using and more information about the problem.

    Cheers,
    Benoit.
  • Hi,

    I tried with Ice::initialize() but the compiler show me:

    error C2660: 'initialize' : function does not take 0 parameters


    I Use ICE 3.2.1 for VC6

    The MFC Demo Working properly.

    If I use for the connection the following code (taken and modified by HelloServer.cpp MFC file Demo):

    Ice::CommunicatorPtr communicator;
    Ice::ObjectAdapterPtr adapter;
    try
    {
    int argc = 0;
    Ice::PropertiesPtr properties = Ice::createProperties();
    properties->load("config");
    communicator = Ice::initializeWithProperties(argc, 0, properties);
    adapter = communicator->createObjectAdapter("OutputReceiver");
    }
    catch(const IceUtil::Exception& ex)
    {
    ostringstream ostr;
    ostr << ex;
    string s = ostr.str();
    AfxMessageBox(CString(s.c_str()), MB_OK|MB_ICONEXCLAMATION);
    return FALSE;
    }


    //
    // Instantiate the servant.
    //
    Ice::ObjectPtr servant = new OutputReceiverI;
    adapter->add(servant, Ice::stringToIdentity("OutputReceiver"));
    adapter->activate();



    The instruction:

    properties->load("config");

    creates exception and joins in the catch block;




    THE file "config" is :

    #
    # The server creates one single object adapter with the name
    # "OutputReceiver". The following line sets the endpoints for this
    # adapter.
    #
    OutputReceiver.Endpoints=tcp -p 10001:udp -p 10001:ssl -p 10002

    #
    # Warn about connection exceptions
    #
    Ice.Warn.Connections=1

    #
    # 0 = no network tracing
    # 1 = trace connection establishment and closure
    # 2 = like 1, but more detailed
    # 3 = like 2, but also trace data transfer
    #
    Ice.Trace.Network=1

    #
    # Protocol Tracing
    #
    # 0 = no protocol tracing
    # 1 = trace protocol messages
    #
    Ice.Trace.Protocol=0

    #
    # Security Tracing
    #
    # 0 = no security tracing
    # 1 = trace warning messages
    # 2 = config file parsing warnings
    #
    IceSSL.Trace.Security=0

    #
    # SSL Configuration File
    #
    # An XML based file that specifies the certificates, keys, SSL version
    # and other pertinent information for creating an SSL connection.
    #
    Ice.Plugin.IceSSL=IceSSL:create
    IceSSL.Server.CertPath=../../../../certs
    IceSSL.Server.Config=sslconfig.xml

    In this block of code, I removed the Part of log messages:

    //LogIPtr log;
    .
    .
    // log = new LogI;
    // communicator->setLogger(log);
    .
    .
    .
    // log->message("Ready to receive requests.");

    This part Is essential for the proper functioning???

    thanks in advance
  • Sorry, I wrote something wrong.

    the instruction that cause exception is :

    communicator = Ice::initializeWithProperties(argc, 0, properties);

    Instead of

    properties->load("config");

    thanks
  • In the catch block,

    the instruction

    AfxMessageBox(CString(s.c_str()), MB_OK|MB_ICONEXCLAMATION);


    Says:


    c:\src\vc60\stage\Ice-3.2.1\src\ice\PluginManagerI.cpp:195:Ice::PluginInitializationException:plug-in initialization failed:failure in entry point 'IceSSL:create'


    thanks

    rogiov
  • benoit
    benoit Rennes, France
    For some reasons the IceSSL plugin can't be loaded. Do you need ssl? If not, you could simply remove the ssl endpoint from the OutputReceiver.Endpoints property definition and comment out the Ice.Plugin.IceSSL property.

    Also, the text of the exception is a bit strange, the line doesn't match the source code of Ice 3.2.1. Did you perhaps made a typo when copying the exception message?

    The definition of the Ice.Plugin.IceSSL property is also wrong, the entry point for the IceSSL plugin in now "IceSSL:createIceSSL".

    Cheers,
    Benoit.
  • You are right. I wrong to write. The message Appears with Ice version 3.0.1 because I also tried to use an old ice version. (the client was not written by me, run under Linux and uses Ice 3.0.1).

    I followed your advice. Now there isn't the SSL exception, but I have the same problem we had the In the first test (in which use Ice::initialize(argc, 0) do You remember?).

    The client fails to connect with the server ice.

    this is the server code:

    InitCommonControls();
    CWinApp::InitInstance();
    try
    {
    Ice::PropertiesPtr properties = Ice::createProperties();
    properties->load("config");
    communicator = Ice::initializeWithProperties(argc, 0,properties);
    adapter = communicator->createObjectAdapter ("OutputReceiver");
    }

    catch(const IceUtil::Exception& ex)
    {
    ostringstream ostr;
    ostr << ex;
    string s = ostr.str();
    AfxMessageBox(CString(s.c_str()),MB_OK|MB_ICONEXCLAMATION);
    return FALSE;
    }

    Ice::ObjectPtr servant = new OutputReceiverI;
    adapter->add(servant, Ice::stringToIdentity("OutputReceiver"));
    adapter->activate();

    In the "config" file I commented (#) all lines except:

    OutputReceiver.Endpoints=tcp -p 10001
    Ice.Warn.Connections=1

    this is the client code;

    Ice::CommunicatorPtr ic;
    OutputReceiverPrx provaIce;
    int status = 0,j = 0;

    DigitalOutput d1;

    try {
    ic = Ice::initialize(argc, argv);
    Ice::ObjectPrx base = ic->stringToProxy("OutputReceiver:tcp -h 172.16.0.18 -p 10001");
    provaIce = OutputReceiverPrx::checkedCast(base);
    if (!provaIce)
    throw "Invalid proxy";

    } catch (const Ice::Exception & ex) {
    cerr << ex << endl;
    status = 1;
    } catch (const char * msg) {
    cerr << msg << endl;
    status = 1;
    }

    d1.id = 123;
    d1.value = 1;
    provaIce->writeDigital(d1);



    the client instruction

    cerr << ex << endl;

    Says:
    c:\src\vc60\stage\Ice-3.0.1\src\ice\Outgoing.cpp:409: Ice::UnknownException:
    unknown exception:
    unknown c++ exception

    With ICE 3.0.1


    If I use the simple code for a small ice server:

    int status = EXIT_SUCCESS;
    Ice::CommunicatorPtr communicator;
    char output_end_point[20];

    try
    {
    argc = 0;
    //communicator = Ice::initialize(argc, argv);
    communicator = Ice::initialize(argc, 0);
    strcpy(output_end_point,"tcp -p ");
    strcat(output_end_point,"10001");
    Ice::ObjectAdapterPtr adapter = communicator->createObjectAdapterWithEndpoints("OutputReceiver", output_end_point);
    adapter->add(new OutputReceiverI, Ice::stringToIdentity("OutputReceiver"));
    adapter->activate();
    communicator->waitForShutdown();
    }

    catch(const Ice::Exception& ex)
    {
    cerr << ex << endl;
    status = EXIT_FAILURE;
    }

    if(communicator)
    {
    try
    {
    communicator->destroy();
    }
    catch(const Ice::Exception& ex)
    {
    cerr << ex << endl;
    status = EXIT_FAILURE;
    }
    }

    return status;
    }


    everything works correctly!

    It is clear that the problem lies in the application where I want to put the server Ice, but I do not know where.

    The VC6 settings should be correct because I complie link and run correctly.
  • benoit
    benoit Rennes, France
    Hi,
    c:\src\vc60\stage\Ice-3.0.1\src\ice\Outgoing.cpp:409: Ice::UnknownException:
    unknown exception:
    unknown c++ exception
    

    This indicates that the client was able to contact the server but the server method dispatch raised an unknown C++ exception. If I understand it correctly, this is raised by the OutputReceiverPrx::checkedCast(base) call.

    The likely reason for this exception is that the server is not correctly built and is mixing debug/optimized runtime C++ libraries. Can you make sure your project is linking with the right Ice libraries?

    See this this FAQ for more information. See also this thread for a similar issue.

    Cheers,
    Benoit.