Archived

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

why subscriber ofen cannot get the data from publisher ?

I modify the code by bernard prompt.
subscriber:



#include "resource.h"

#include <IceUtil/IceUtil.h>
#include <Ice/Ice.h>
#include <IceStorm/IceStorm.h>
#include "Monitor.h"
#include <Windows.h>
//读写文件
#include <iostream>//cout


........
........
........


struct INITIALLIZE
{
Ice::CommunicatorPtr communicator;
IceStorm::TopicManagerPrx manager;
Ice::ObjectAdapterPtr adapter;
};
INITIALLIZE initializeSub(int argc, char** argv)
{
//initialize communicator
INITIALLIZE initializeptr;
Ice::CommunicatorPtr communicator;
Ice::InitializationData initData;
initData.properties = Ice::createProperties();

string config = "config.sub";
try
{
initData.properties->load(config);
}
catch(const Ice::FileException&)
{
exit(0);
}
communicator = Ice::initialize(argc, argv, initData);
cout<<"communicator is :"<<communicator<<endl;
//initialize manager
enum Option { None, Datagram, Twoway, Oneway, Ordered};
Option option = None;
option = Oneway;
IceStorm::TopicManagerPrx manager = IceStorm::TopicManagerPrx::checkedCast(
communicator->propertyToProxy("TopicManager.Proxy"));
cout<<"manager is :"<<manager<<endl;
if(!manager)
{
printf("invalid proxy !\n");
//return EXIT_FAILURE;
}
//initialize adapter
Ice::ObjectAdapterPtr adapter;
adapter = communicator->createObjectAdapter("Transporter.Subscriber");
cout<<"adapter is : "<<adapter<<endl;
initializeptr.manager=manager;
initializeptr.communicator=communicator;
initializeptr.adapter=adapter;
return initializeptr;
}

//- create your subscriber
//- retrieve or create topic1, topic2, topic3 (etc.)
//- register your subscriber with each topic

static int times=0;
int Sub(const string& topicName, const INITIALLIZE& Initializationptr)
{
++times;
Ice::CommunicatorPtr communicator=Initializationptr.communicator;
IceStorm::TopicManagerPrx manager=Initializationptr.manager;
Ice::ObjectAdapterPtr adapter=Initializationptr.adapter;
IceStorm::TopicPrx topic;
try
{
topic = manager->retrieve(topicName);
}
catch(const IceStorm::NoSuchTopic&)
{
try
{
topic = manager->create(topicName);
}
catch(const IceStorm::TopicExists&)
{
printf("temporary failure. try again.\n");
return EXIT_FAILURE;
}
}
Ice::Identity subId;
subId.name = topicName;
if(subId.name.empty())
{
subId.name = IceUtil::generateUUID();
}
Ice::ObjectPrx subscriber;
subscriber = adapter->add(new TransporterI, subId);
subscriber = subscriber->ice_oneway();
// subscriber = subscriber->ice_twoway();

IceStorm::QoS qos;
qos["reliability"] = "";

try
{
topic->subscribeAndGetPublisher(qos, subscriber);
}
catch(const IceStorm::AlreadySubscribed&)
{
//cout << "reactivating persistent subscriber" << endl;
printf("reactivating persistent subscriber\n");
}
if (times==1)
{
adapter->activate();
}
cout<<"订阅主题为"<<topicName<<endl;

communicator->waitForShutdown();
cout<<"等待结束"<<endl;
return EXIT_SUCCESS;
}


int main(int argc, char** argv)
{
INITIALLIZE Initializationptr=initializeSub( argc, argv );//初始化
Sub("Weather",Initializationptr);
// Sleep(120000);
}


when I run subscriber to get dada from publisher many times only one or two time receive data from publisher ?
I check the code carefully many times but can not find the bug !
Who can tell me the reason?
What should I modify the subscriber code to receive data steady?
Thanks a lot !

Today, in china ,it is the Mid-Autumn Festival ,best wishes for bernard and everyone in the www.zero.com!

Comments

  • bernard
    bernard Jupiter, FL
    Hello,

    Hope you're enjoying your Mid-Autumn Festival!

    The code you posted does not do the following:
    //- create your subscriber
    //- retrieve or create topic1, topic2, topic3 (etc.)
    //- register your subscriber with each topic

    I am not sure what you're trying to do. In any case, I recommend you have a look at the IceStorm C++ demo included in your Ice distribution: make sure you understand the demo and then update this demo to add more subscribers and/or publishers.

    Best regards,
    Bernard
  • Thank you very much for your reply!

    Hi,Bernard!

    The code is changed from the the demo clock ,My goal is to use the one interface but different topicNames for subscriber and publisher.
    Because you tell me “All this is usually done only once for your application:
    - create a new object adapter each time
    - active this object adapter
    -- call communicator->waitForShutdown”
    In order to obey the rule “All this is usually done only”,I write a function” INITIALLIZE initializeSub”and return only one adapter , one communicator and one manager for the sub function to use 。the code as follow:
    INITIALLIZE initializeSub(int argc, char** argv)
    {
    //initialize communicator
    INITIALLIZE initializeptr;
    Ice::CommunicatorPtr communicator;
    Ice::InitializationData initData;
    initData.properties = Ice::createProperties();

    string config = "config.sub";
    try
    {
    initData.properties->load(config);
    }
    catch(const Ice::FileException&)
    {
    exit(0);
    }
    communicator = Ice::initialize(argc, argv, initData);
    cout<<"communicator is :"<<communicator<<endl;
    //initialize manager
    enum Option { None, Datagram, Twoway, Oneway, Ordered};
    Option option = None;
    option = Oneway;
    IceStorm::TopicManagerPrx manager = IceStorm::TopicManagerPrx::checkedCast(
    communicator->propertyToProxy("TopicManager.Proxy"));
    cout<<"manager is :"<<manager<<endl;
    if(!manager)
    {
    printf("invalid proxy !\n");
    }
    //initialize adapter
    Ice::ObjectAdapterPtr adapter;
    adapter = communicator->createObjectAdapter("Transporter.Subscriber");
    //save manager communicator adapter
    cout<<"adapter is : "<<adapter<<endl;
    initializeptr.manager=manager;
    initializeptr.communicator=communicator;
    initializeptr.adapter=adapter;
    return initializeptr;//1为成功
    }
    when I want to subscriber different topic I will call “sub” function to or create topic1, topic2, topic3 (etc.),the sub code as follows:
    static int times=0;
    int Sub(const string& topicName, const INITIALLIZE& Initializationptr)
    {
    ++times;
    Ice::CommunicatorPtr communicator=Initializationptr.communicator;
    IceStorm::TopicManagerPrx manager=Initializationptr.manager;
    Ice::ObjectAdapterPtr adapter=Initializationptr.adapter;
    IceStorm::TopicPrx topic;
    try
    {
    topic = manager->retrieve(topicName);
    }
    catch(const IceStorm::NoSuchTopic&)
    {
    try
    {
    topic = manager->create(topicName);
    }
    catch(const IceStorm::TopicExists&)
    {
    printf("temporary failure. try again.\n");
    return EXIT_FAILURE;
    }
    }
    Ice::Identity subId;
    subId.name = topicName;
    if(subId.name.empty())
    {
    subId.name = IceUtil::generateUUID();
    }
    Ice::ObjectPrx subscriber;
    subscriber = adapter->add(new TransporterI, subId);
    subscriber = subscriber->ice_oneway();
    // subscriber = subscriber->ice_twoway();

    IceStorm::QoS qos;
    qos["reliability"] = "";
    try
    {
    topic->subscribeAndGetPublisher(qos, subscriber);
    }
    catch(const IceStorm::AlreadySubscribed&)
    {
    //cout << "reactivating persistent subscriber" << endl;
    printf("reactivating persistent subscriber\n");
    }
    if (times==1)
    {
    adapter->activate();
    }
    cout<<"订阅主题为"<<topicName<<endl;
    //shutdownOnInterrupt();
    //communicator->waitForShutdown();
    cout<<"等待结束"<<endl;
    return EXIT_SUCCESS;
    }
    when I run subscriber to get dada from publisher many times only one or two time receive data from publisher ?
    I check the code carefully many times but can not find the bug !
    Who can tell me the reason?
    What should I modify the subscriber code to receive data steady?
    Thanks a lot !
  • it really strange exception !

    Hi,bernard!


    when I run the subscriber:

    int main(int argc, char** argv)

    {

    INITIALLIZE Initializationptr=initializeSub( argc, argv );//初始化

    Sub("Weather",Initializationptr);

    Sub("wonderful",Initializationptr);//订阅

    Sleep(120000);

    }

    the prompt in the icebox-IceStorm is as follows:

    -- 09/14/11 08:10:40.640 icebox-IceStorm: Topic: Weather: subscribeAndGetPublish

    er: Weather

    -- 09/14/11 08:10:40.656 icebox-IceStorm: Topic: wonderful: subscribeAndGetPubli

    sher: wonderful



    When I run the publisher, the prompt in the icebox-IceStorm:

    -- 09/14/11 08:14:24.718 icebox-IceStorm: Subscriber: 00EB5F78 wonderful: subscr

    iber errored out: Network.cpp:1387: Ice::ConnectionRefusedException:

    connection refused: 远程系统拒绝网络连接。 retry: 0/0

    -- 09/14/11 08:14:24.734 icebox-IceStorm: Subscriber: 00EB5368 Weather: subscrib

    er errored out: Network.cpp:1387: Ice::ConnectionRefusedException:

    connection refused: 远程系统拒绝网络连接。 retry: 0/0



    However,sometimes,subscriber can receive dada from pulisher normally.so I am very confused.

    What is wrong with code ?

    can you help me solve the problem?
    (the operating environment is vs 2008, ICE 3.4.1 ,windowsxp)

    thank you very much .
  • it really strange exception !

    I trace the code with different parameters at subscriber as follow:
    //when I run the function : INITIALLIZE Initializationptr=initializeSub( argc, argv );
    communicator is :1
    manager is :DemoIceStorm/TopicManager -t:tcp -h 127.0.0.1 -p 10000
    adapter is : 1
    //when I run the subscriber function Sub("Weather",Initializationptr);
    Weather‘s topic is: DemoIceStorm/topic.Weather -t:tcp -h 192.168.1.2 -p 10000
    Weather's subId.name is:6071338f-e0f3-47cf-95b6-5cfa8e02da43
    subscriber is :6071338f-e0f3-47cf-95b6-5cfa8e02da43 -t:tcp -h 192.168.1.2 -p 3778:
    udp -h 192.168.1.2 -p 3779
    //when I run the subscriber function Sub("wonderful",Initializationptr);

    wonderful's topic is: DemoIceStorm/topic.wonderful -t:tcp -h 192.168.1.2 -p 10000

    wonderful's subId.name is:89bbe799-bd68-4e29-a489-82e0940b7c4a
    subscriber is:89bbe799-bd68-4e29-a489-82e0940b7c4a -t:tcp -h 192.168.1.2 -p 3778:
    udp -h 192.168.1.2 -p 3779
    //when I run the publisher ,the subscriber receive messge as follow:
    -! 09/14/11 20:20:32.421 warning: dispatch exception: C:\Ice-Build\VC9\Debug\cpp
    \include\Ice/BasicStream.h:341: Ice::UnmarshalOutOfBoundsException:
    protocol error: out of bounds during unmarshaling
    identity: 89bbe799-bd68-4e29-a489-82e0940b7c4a
    facet:
    operation: sendPerson
    -! 09/14/11 20:20:32.453 warning: dispatch exception: C:\Ice-Build\VC9\Debug\cpp
    \include\Ice/BasicStream.h:341: Ice::UnmarshalOutOfBoundsException:
    protocol error: out of bounds during unmarshaling
    identity: 6071338f-e0f3-47cf-95b6-5cfa8e02da43
    facet:
    operation: sendPerson

    However,sometimes I can receive the data from the publisher by sendPerson.
    but,more times,I can only recive the messge like this:protocol error: out of bounds during unmarshaling
  • bernard
    bernard Jupiter, FL
    OutOfBoundMarshalException typically indicates a mismatch between the Slice definitions of your client and server (here publisher and subscriber); see Why do I get an UnmarshalOutOfBoundsException? - ZeroC Documentation - ZeroC.

    You should re-translate your Slice files and make sure everything is in sync!

    Also, I'd replace the
    Sleep(120000);
    

    with
    communicator->waitForShutdown();
    

    (you could also use an Ice::Application, to simplify signal handling)

    Best regards,
    Bernard
  • thank you very much for your reply !

    Hi bernard!
    thank you very much for your reply !
    I will modify the code by your advice.
    best regards.
    Best regards,
    wang teng
  • thanks very much .

    the problem has been sloved.
    the reason is here :
    subId.name=topicName
    should modify:
    sting id;
    subId.name=id.

    best regard
    wang teng
  • bernard
    bernard Jupiter, FL
    It's good to see you figured it out!

    The identity of your subscriber should not matter, as long as all your subscribers have distinct (and preferably unique) identities.

    Best regards,
    Bernard
  • Thank you very much for your reply!

    Best regards!
    wang teng