示例#1
0
ObserverTopic::ObserverTopic(const IceStorm::TopicManagerPrx& topicManager, const string& name, Ice::Long dbSerial) :
    _logger(topicManager->ice_getCommunicator()->getLogger()), _serial(0), _dbSerial(dbSerial)
{
    for(int i = 0; i < static_cast<int>(sizeof(encodings) / sizeof(Ice::EncodingVersion)); ++i)
    {
        ostringstream os;
        os << name << "-" << Ice::encodingVersionToString(encodings[i]);
        IceStorm::TopicPrx t;
        try
        {
            t = topicManager->create(os.str());
        }
        catch(const IceStorm::TopicExists&)
        {
            t = topicManager->retrieve(os.str());
        }

        //
        // NOTE: collocation optimization needs to be turned on for the
        // topic because the subscribe() method is given a fixed proxy
        // which can't be marshalled.
        //
        _topics[encodings[i]] = t->ice_collocationOptimized(true);
        _basePublishers.push_back(
            t->getPublisher()->ice_collocationOptimized(false)->ice_encodingVersion(encodings[i]));
    }
}
示例#2
0
serverI::serverI(char* ipToSet, char *portToSet){

	port = portToSet;
	ip = ipToSet;
	ic = Ice::initialize();

	cout<<"----- Initialisation des fichiers audio :";
	if(initFiles())
		cout<<" OK"<<endl;	
	else{
		cerr << " Erreur" << endl;
		exit(1);
	}
        	
	cout<<"----- Initialisation du Topic :";

	// PREPARE TOPIC FOR PUBLISHING
	string topicName = "serv";
	
	Ice::ObjectPrx obj = ic->stringToProxy("server/TopicManager:tcp -h "+ip+" -p 10000");
	IceStorm::TopicManagerPrx manager = IceStorm::TopicManagerPrx::checkedCast(obj);
	if(!manager)
    	{

        exit(1);
    	}
	IceStorm::TopicPrx topic;
    try
    {
	   cout<<"OK"<<endl;
        topic = manager->retrieve(topicName);
    }
    catch(const IceStorm::NoSuchTopic&)
    {
        try
        {
		  cout<<"OK"<<endl;
            topic = manager->create(topicName);
        }
        catch(const IceStorm::TopicExists&)
        {
		  cout<<"Error"<<endl;
            exit(1);
        }
	}
	
    Ice::ObjectPrx publisher = topic->getPublisher();
    publisher = publisher->ice_oneway();
    serv = MonitorPrx::uncheckedCast(publisher);

    cout<<"----- Lancement du serveur "<<endl;
    initStreaming();
}
示例#3
0
bool Publisher::Startup(void)
{
    this->IceInitialize();

    IceStorm::TopicManagerPrx manager;
    try {
        manager = IceStorm::TopicManagerPrx::checkedCast(this->IceCommunicator->propertyToProxy("TopicManager.Proxy"));
    } catch (const Ice::ConnectionRefusedException & e) {
        SCLOG_ERROR << PUBLISHER_INFO << "Failed to initialize IceStorm.  Check if IceBox is running: " << e.what() << std::endl;
        return false;
    }

    if (!manager) {
        SCLOG_ERROR << PUBLISHER_INFO << "Invalid proxy" << std::endl;
        return false;
    }

    // Retrieve the topic.
    IceStorm::TopicPrx topic;
    try {
        topic = manager->retrieve(this->TopicName);
    } catch(const IceStorm::NoSuchTopic&) {
        try {
            topic = manager->create(this->TopicName);
        }
        catch(const IceStorm::TopicExists&) {
            SCLOG_ERROR << PUBLISHER_INFO << "Topic not found. Try again." << std::endl;
            return false;
        }
    }

    // Get the topic's publisher object, and create topic proxy
    Ice::ObjectPrx publisher = topic->getPublisher();

    // Get the topic's publisher object, and create a proper proxy depending on
    // the topic.
    switch (this->Topic) {
    case Topic::CONTROL:
        PublisherControl = ControlPrx::uncheckedCast(publisher);
        break;
    case Topic::DATA:
        PublisherData = DataPrx::uncheckedCast(publisher);
        break;
    default:
        SCASSERT(false);
    }

    //BaseType::Startup();

    return true;
}
示例#4
0
int
Publisher::run(int argc, char* argv[])
{
    Ice::PropertiesPtr properties = communicator()->getProperties();

    IceStorm::TopicManagerPrx manager = 
        IceStorm::TopicManagerPrx::checkedCast(communicator()->stringToProxy("DemoIceStorm/TopicManager"));
    if(manager == 0)
    {
        cerr << appName() << ": no topic manager found, make sure application was deployed." << endl;
        return EXIT_FAILURE;
    }

    string topicName = "time";
    if(argc != 1)
    {
        topicName = argv[1];
    }

    IceStorm::TopicPrx topic;
    try
    {
        topic = manager->retrieve(topicName);
    }
    catch(const IceStorm::NoSuchTopic&)
    {
        cerr << appName() << ": topics not created yet, run subscriber." << endl;
        return EXIT_FAILURE;
    }

    //
    // Get the topic's publisher object, and configure a Clock proxy
    // with per-request load balancing.
    //
    ClockPrx clock = ClockPrx::uncheckedCast(topic->getPublisher()->ice_oneway()->ice_connectionCached(false));

    try
    {
        while(true)
        {
            clock->tick(IceUtil::Time::now().toDateTime());
            IceUtil::ThreadControl::sleep(IceUtil::Time::seconds(1));
        }
    }
    catch(const Ice::CommunicatorDestroyedException&)
    {
        // Ignore
    }

    return EXIT_SUCCESS;
}
示例#5
0
void 
ProgressMonitor::unsubscribe()
{
    if ( !topic_.isEmpty() )
    {
        IceStorm::TopicPrx topicPrx;
        topic_.get( topicPrx );

        topicPrx->unsubscribe( consumerPrx_ );
        std::stringstream ss;
        ss << "Unsubscribed from " << topicPrx->ice_toString();
        context_.tracer().debug( ss.str() );
    }
}
示例#6
0
ReplicaCache::ReplicaCache(const Ice::CommunicatorPtr& communicator, const IceStorm::TopicManagerPrx& topicManager) :
    _communicator(communicator)
{
    IceStorm::TopicPrx t;
    try
    {
        t = topicManager->create("ReplicaObserverTopic");
    }
    catch(const IceStorm::TopicExists&)
    {
        t = topicManager->retrieve("ReplicaObserverTopic");
    }

    const_cast<IceStorm::TopicPrx&>(_topic) = IceStorm::TopicPrx::uncheckedCast(t->ice_collocationOptimized(true));
    const_cast<ReplicaObserverPrx&>(_observers) = ReplicaObserverPrx::uncheckedCast(_topic->getPublisher());
}
示例#7
0
int main(int argc, char** argv){
  int status;
  Ice::CommunicatorPtr ic;

  try{
    ic = Ice::initialize(argc,argv);
    std::string topicName = ic->getProperties()->getProperty("Cameraview_icestorm.Camera.TopicName");

	std::cout << "Trying to conect to: " << topicName << std::endl;

    Ice::ObjectPrx obj=ic->propertyToProxy("Cameraview_icestorm.Camera.TopicManager");
    IceStorm::TopicManagerPrx topicManager=IceStorm::TopicManagerPrx::checkedCast(obj);

    std::string objAdapterEndpoint = ic->getProperties()->getProperty("Cameraview_icestorm.Camera.ObjectAdapter");
    Ice::ObjectAdapterPtr adapter=ic->createObjectAdapterWithEndpoints("CameraAdapter",objAdapterEndpoint);

    ImageConsumerI* imageConsumer = new ImageConsumerI;
    Ice::ObjectPrx proxy = adapter->addWithUUID(imageConsumer)->ice_oneway();

    IceStorm::TopicPrx topic;
    try {
        topic = topicManager->retrieve(topicName);
        IceStorm::QoS qos;
        topic->subscribeAndGetPublisher(qos, proxy);
    }
    catch (const IceStorm::NoSuchTopic& ex) {
        std::cerr << ex << std::endl;
    }

    adapter->activate();
    ic->waitForShutdown();

    topic->unsubscribe(proxy);

    if (ic)
    	ic->destroy();
    return status;

  }catch (const Ice::Exception& ex) {
    std::cerr << ex << std::endl;
    status = 1;
  } catch (const char* msg) {
    std::cerr << msg << std::endl;
    status = 1;
  }
}
示例#8
0
int
Subscriber::run(int argc, char* argv[])
{
    Ice::StringSeq args = Ice::argsToStringSeq(argc, argv);
    args = communicator()->getProperties()->parseCommandLineOptions("Clock", args);
    Ice::stringSeqToArgs(args, argc, argv);

    bool batch = false;
    enum Option { None, Datagram, Twoway, Oneway, Ordered};
    Option option = None;
    string topicName = "time";
    string id;
    string retryCount;
    int i;

    for(i = 1; i < argc; ++i)
    {
        string optionString = argv[i];
        Option oldoption = option;
        if(optionString == "--datagram")
        {
            option = Datagram;
        }
        else if(optionString == "--twoway")
        {
            option = Twoway;
        }
        else if(optionString == "--oneway")
        {
            option = Oneway;
        }
        else if(optionString == "--ordered")
        {
            option = Ordered;
        }
        else if(optionString == "--batch")
        {
            batch = true;
        }
        else if(optionString == "--id")
        {
            ++i;
            if(i >= argc)
            {
                usage(argv[0]);
                return EXIT_FAILURE;
            }
            id = argv[i];
        }
        else if(optionString == "--retryCount")
        {
            ++i;
            if(i >= argc)
            {
                usage(argv[0]);
                return EXIT_FAILURE;
            }
            retryCount = argv[i];
        }
        else if(optionString.substr(0, 2) == "--")
        {
            usage(argv[0]);
            return EXIT_FAILURE;
        }
        else
        {
            topicName = argv[i++];
            break;
        }

        if(oldoption != option && oldoption != None)
        {
            usage(argv[0]);
            return EXIT_FAILURE;
        }
    }

    if(i != argc)
    {
        usage(argv[0]);
        return EXIT_FAILURE;
    }

    if(!retryCount.empty())
    {
        if(option == None)
        {
            option = Twoway;
        }
        else if(option != Twoway && option != Ordered)
        {
            cerr << argv[0] << ": retryCount requires a twoway proxy" << endl;
            return EXIT_FAILURE;
        }
    }

    if(batch && (option == Twoway || option == Ordered))
    {
        cerr << argv[0] << ": batch can only be set with oneway or datagram" << endl;
        return EXIT_FAILURE;
    }

    IceStorm::TopicManagerPrx manager = IceStorm::TopicManagerPrx::checkedCast(
        communicator()->propertyToProxy("TopicManager.Proxy"));
    if(!manager)
    {
        cerr << appName() << ": invalid proxy" << endl;
        return EXIT_FAILURE;
    }

    IceStorm::TopicPrx topic;
    try
    {  
        topic = manager->retrieve(topicName);
    }
    catch(const IceStorm::NoSuchTopic&)
    {
        try
        {
            topic = manager->create(topicName);
        }
        catch(const IceStorm::TopicExists&)
        {
            cerr << appName() << ": temporary failure. try again." << endl;
            return EXIT_FAILURE;
        }
    }

    Ice::ObjectAdapterPtr adapter = communicator()->createObjectAdapter("Clock.Subscriber");

    //
    // Add a servant for the Ice object. If --id is used the identity
    // comes from the command line, otherwise a UUID is used.
    //
    // id is not directly altered since it is used below to detect
    // whether subscribeAndGetPublisher can raise AlreadySubscribed.
    //
    Ice::Identity subId;
    subId.name = id;
    if(subId.name.empty())
    {
        subId.name = IceUtil::generateUUID();
    }
    Ice::ObjectPrx subscriber = adapter->add(new ClockI, subId);

    //
    // Activate the object adapter before subscribing.
    //
    adapter->activate();

    IceStorm::QoS qos;
    if(!retryCount.empty())
    {
        qos["retryCount"] = retryCount;
    }

    //
    // Set up the proxy.
    //
    if(option == Datagram)
    {
        if(batch)
        {
            subscriber = subscriber->ice_batchDatagram();
        }
        else
        {
            subscriber = subscriber->ice_datagram();
        }
    }
    else if(option == Twoway)
    {
        // Do nothing to the subscriber proxy. Its already twoway.
    }
    else if(option == Ordered)
    {
        // Do nothing to the subscriber proxy. Its already twoway.
        qos["reliability"] = "ordered";
    }
    else if(option == Oneway || option == None)
    {
        if(batch)
        {
            subscriber = subscriber->ice_batchOneway();
        }
        else
        {
            subscriber = subscriber->ice_oneway();
        }
    }

    try
    {
        topic->subscribeAndGetPublisher(qos, subscriber);
    }
    catch(const IceStorm::AlreadySubscribed&)
    {
        // If we're manually setting the subscriber id ignore.
        if(id.empty())
        {
            throw;
        }
        cout << "reactivating persistent subscriber" << endl;
    }

    shutdownOnInterrupt();
    communicator()->waitForShutdown();

    topic->unsubscribe(subscriber);

    return EXIT_SUCCESS;
}
示例#9
0
CounterI::CounterI(const IceStorm::TopicPrx& topic) :
    _value(0),
    _topic(topic),
    _publisher(CounterObserverPrx::uncheckedCast(topic->getPublisher()))
{
}
示例#10
0
void main()
{
	Ice::InitializationData initData;
	initData.properties = Ice::createProperties();
	initData.properties->setProperty("Ice.MessageSizeMax", "102400" );//默认是1024,单位KB
	initData.properties->setProperty("Ice.ThreadPool.Server.Size", "1");
	initData.properties->setProperty("Ice.ThreadPool.Server.SizeMax", "1000" );
	initData.properties->setProperty("Ice.ThreadPool.Server.SizeWarn", "1024");
	Ice::CommunicatorPtr communicatorPtr = Ice::initialize(initData);

	char szStormHost[100]={0};
	char szStromPort[10]={0};

	char szDir[MAX_PATH] = {0};
	GetModuleFileName(NULL,szDir,MAX_PATH);
	string strIniFile = szDir;
	strIniFile = strIniFile.substr(0,strIniFile.length()-3) + "ini";

	GetPrivateProfileString("NewsPub","StormHost","localhost",szStormHost,100,strIniFile.c_str());
	WritePrivateProfileString("NewsPub","StormHost",szStormHost,strIniFile.c_str());

	GetPrivateProfileString("NewsPub","StromPort","10000",szStromPort,100,strIniFile.c_str());
	WritePrivateProfileString("NewsPub","StromPort",szStromPort,strIniFile.c_str());

	char szStr[1000]={0};
	sprintf_s(szStr,"StormNewsDemo/TopicManager:tcp -h %s -p %s",szStormHost,szStromPort);

	// icestorm的地址"StormNewsDemo/TopicManager:tcp -h xiangzhenwei.peraportal.com -p 10000"
	IceStorm::TopicManagerPrx manager = NULL;
	try
	{
		manager = IceStorm::TopicManagerPrx::checkedCast(communicatorPtr->stringToProxy(szStr));
	}
	catch (const Ice::Exception &e)
	{
		cerr << e.what();
		return;
	}

	if(!manager)
	{
		cerr << "NewsSub.exe" << ": invalid proxy" << endl;
		return;
	}

	IceStorm::TopicPrx topic;
	try
	{  
		topic = manager->retrieve("news");
	}
	catch(const IceStorm::NoSuchTopic&)
	{
		try
		{
			topic = manager->create("news");
		}
		catch(const IceStorm::TopicExists&)
		{
			cerr << "NewsSub.exe" << ": temporary failure. try again." << endl;
			return;
		}
	}
	// 接收端监听消息的地址"tcp -h 0.0.0.0:udp -h 0.0.0.0"
	string strEndPoint = "tcp -h 0.0.0.0:udp -h 0.0.0.0";
	Ice::ObjectAdapterPtr adapter = communicatorPtr->createObjectAdapterWithEndpoints("News.Subscriber", strEndPoint );

	//
	// Add a servant for the Ice object. If --id is used the identity
	// comes from the command line, otherwise a UUID is used.
	//
	// id is not directly altered since it is used below to detect
	// whether subscribeAndGetPublisher can raise AlreadySubscribed.
	//
	Ice::Identity subId;
	subId.name = IceUtil::generateUUID();
	Ice::ObjectPrx subscriber = adapter->add(new NewsI, subId);
	g_strClientId = subId.name;

	Ice::CommunicatorPtr communicatorPtr2 = InitCommunicator();
	char szEndPoints[1000]={0};
	sprintf_s(szEndPoints,"Pera601DemoServerService:tcp -h %s -p %s -t 5000", szStormHost, "20131");
	try
	{
		PcIdToWsServerPrx m_pPrx = PcIdToWsServerPrx::checkedCast(communicatorPtr2->stringToProxy(szEndPoints));
		m_pPrx = m_pPrx->ice_twoway()->ice_timeout(20000)->ice_secure(false);
		m_pPrx->TellClientId(subId.name);	 	
	}
	catch(const Ice::Exception& ex)
	{
		printf("远程调用服务端失败,ICE异常:%s", ex.ice_name().c_str());
		return;
	}


	//
	// Activate the object adapter before subscribing.
	//
	adapter->activate();
	subscriber = subscriber->ice_oneway();
	 IceStorm::QoS qos;
	 qos["retryCount"] = 3;

	try
	{
		topic->subscribeAndGetPublisher(qos, subscriber);
	}
	catch(const IceStorm::AlreadySubscribed&)
	{
		// If we're manually setting the subscriber id ignore.
		cout << "reactivating persistent subscriber" << endl;
	}

	communicatorPtr->waitForShutdown();
	topic->unsubscribe(subscriber);
}
示例#11
0
int Producer::run(int argc, char* argv[])
{
    EnabledMap::iterator it;

    IceUtil::Mutex::Lock broadcastLock(broadcastMutex);
    broadcastLock.release();

    // start up Ice server
    Ice::ObjectAdapterPtr adapter = communicator()->createObjectAdapterWithEndpoints("ImageProvider", PRODUCER_ENDPOINT);
    Ice::Identity id = communicator()->stringToIdentity("ImageProvider");
    adapter->add(this, id);
    adapter->activate();

    // get topic manager
    topicManager = IceStorm::TopicManagerPrx::checkedCast(communicator()->stringToProxy(TOPIC_MANAGER));

    // get topic proxies to publish to
    IceStorm::TopicPrx embeddedTopicPrx;
    IceStorm::TopicPrx sharedMemoryTopicPrx;
    try
    {
        embeddedTopicPrx = topicManager->retrieve("ImageReceiverEmbedded");
    }
    catch (const IceStorm::NoSuchTopic&)
    {
        embeddedTopicPrx = topicManager->create("ImageReceiverEmbedded");
    }
    try
    {
        sharedMemoryTopicPrx = topicManager->retrieve("ImageReceiverSharedMemory");
    }
    catch (const IceStorm::NoSuchTopic&)
    {
        sharedMemoryTopicPrx = topicManager->create("ImageReceiverSharedMemory");
    }

    embeddedTopic = ImageReceiverEmbeddedPrx::uncheckedCast(embeddedTopicPrx->getPublisher()->ice_oneway());
    sharedMemoryTopic = ImageReceiverSharedMemoryPrx::uncheckedCast(sharedMemoryTopicPrx->getPublisher()->ice_oneway());

    while (!communicator()->isShutdown())
    {
        // broadcast data
        broadcastLock.acquire();

        for (it = broadcastEnabled.begin(); it != broadcastEnabled.end(); ++it)
        {
            if (it->second > 0)
            {
                // TODO: broadcast correct image type based on it->first.second
                switch (it->first.first)
                {
                    case Embedded:
                        embeddedTopic->receiveImageEmbedded(Blob(), it->first.second);
                    break;

                    case SharedMemory:
                        sharedMemoryTopic->receiveImageSharedMemory(SharedMemorySegment(), it->first.second);
                    break;
                }
            }
        }

        broadcastLock.release();

        // "wait" for next image
        IceUtil::ThreadControl::sleep(IceUtil::Time::milliSeconds(30)); // ~30 images/second
    }

    return 0;
}
示例#12
0
文件: AllTests.cpp 项目: Jonavin/ice
void
allTests(const Ice::CommunicatorPtr& communicator)
{
    {
        cout << "Testing Glacier2 stub... " << flush;
        char** argv = 0;
        int argc = 0;
        SessionHelperClient client;
        client.run(argc, argv);
        cout << "ok" << endl;
    }

    {
        cout << "Testing IceStorm stub... " << flush;
        IceStorm::TopicManagerPrx manager =
                    IceStorm::TopicManagerPrx::uncheckedCast(communicator->stringToProxy("test:default -p 12010"));

        IceStorm::QoS qos;
        IceStorm::TopicPrx topic;
        string topicName = "time";

        try
        {
            topic = manager->retrieve(topicName);
            test(false);
        }
        catch(const IceStorm::NoSuchTopic&)
        {
            test(false);
        }
        catch(const Ice::LocalException&)
        {
        }

        Ice::ObjectAdapterPtr adapter = communicator->createObjectAdapterWithEndpoints("subscriber" ,"tcp");
        Ice::ObjectPrx subscriber = adapter->addWithUUID(new ClockI);
        adapter->activate();
        try
        {
            topic->subscribeAndGetPublisher(qos, subscriber);
            test(false);
        }
        catch(const IceStorm::AlreadySubscribed&)
        {
            test(false);
        }
        catch(const IceUtil::NullHandleException&)
        {
        }
        cout << "ok" << endl;
    }

    {
        cout << "Testing IceGrid stub... " << flush;

        Ice::ObjectPrx base = communicator->stringToProxy("test:default -p 12010");
        IceGrid::RegistryPrx registry = IceGrid::RegistryPrx::uncheckedCast(base);
        IceGrid::AdminSessionPrx session;
        IceGrid::AdminPrx admin;
        try
        {
            session = registry->createAdminSession("username", "password");
            test(false);
        }
        catch(const IceGrid::PermissionDeniedException&)
        {
            test(false);
        }
        catch(const Ice::LocalException&)
        {
        }

        try
        {
            admin = session->getAdmin();
            test(false);
        }
        catch(const IceUtil::NullHandleException&)
        {
        }
        cout << "ok" << endl;
    }
}
示例#13
0
int
Publisher::run(int argc, char* argv[])
{
    enum Option { None, Datagram, Twoway, Oneway };
    Option option = None;
    string topicName = "time";
    int i;

    for(i = 1; i < argc; ++i)
    {
        string optionString = argv[i];
        Option oldoption = option;
        if(optionString == "--datagram")
        {
            option = Datagram;
        }
        else if(optionString == "--twoway")
        {
            option = Twoway;
        }
        else if(optionString == "--oneway")
        {
            option = Oneway;
        }
        else if(optionString.substr(0, 2) == "--")
        {
            usage(argv[0]);
            return EXIT_FAILURE;
        }
        else
        {
            topicName = argv[i++];
            break;
        }

        if(oldoption != option && oldoption != None)
        {
            usage(argv[0]);
            return EXIT_FAILURE;
        }
    }

    if(i != argc)
    {
        usage(argv[0]);
        return EXIT_FAILURE;
    }

    IceStorm::TopicManagerPrx manager = IceStorm::TopicManagerPrx::checkedCast(
        communicator()->propertyToProxy("TopicManager.Proxy"));
    if(!manager)
    {
        cerr << appName() << ": invalid proxy" << endl;
        return EXIT_FAILURE;
    }

    //
    // Retrieve the topic.
    //
    IceStorm::TopicPrx topic;
    try
    {
        topic = manager->retrieve(topicName);
    }
    catch(const IceStorm::NoSuchTopic&)
    {
        try
        {
            topic = manager->create(topicName);
        }
        catch(const IceStorm::TopicExists&)
        {
            cerr << appName() << ": temporary failure. try again." << endl;
            return EXIT_FAILURE;
        }
    }

    //
    // Get the topic's publisher object, and create a Clock proxy with
    // the mode specified as an argument of this application.
    //
    Ice::ObjectPrx publisher = topic->getPublisher();
    if(option == Datagram)
    {
        publisher = publisher->ice_datagram();
    }
    else if(option == Twoway)
    {
        // Do nothing.
    }
    else if(option == Oneway || option == None)
    {
        publisher = publisher->ice_oneway();
    }
    
    ClockPrx clock = ClockPrx::uncheckedCast(publisher);

    cout << "publishing tick events. Press ^C to terminate the application." << endl;
    try
    {
        while(true)
        {
            clock->tick(IceUtil::Time::now().toDateTime());
            IceUtil::ThreadControl::sleep(IceUtil::Time::seconds(1));
        }
    }
    catch(const Ice::CommunicatorDestroyedException&)
    {
        // Ignore
    }

    return EXIT_SUCCESS;
}
示例#14
0
int
Publisher::run(int argc, char* argv[])
{
    IceUtil::Options opts;
    opts.addOpt("", "datagram");
    opts.addOpt("", "twoway");
    opts.addOpt("", "oneway");

    IceUtil::Options::StringVector remaining;
    try
    {
        remaining = opts.parse(argc, (const char**)argv);
    }
    catch(const IceUtil::BadOptException& e)
    {
        cerr << argv[0] << ": " << e.reason << endl;
        return EXIT_FAILURE;
    }

    IceStorm::TopicManagerPrx manager = IceStorm::TopicManagerPrx::checkedCast(
        communicator()->propertyToProxy("IceStorm.TopicManager.Proxy"));
    if(!manager)
    {
        cerr << appName() << ": invalid proxy" << endl;
        return EXIT_FAILURE;
    }

    string topicName = "time";
    if(!remaining.empty())
    {
        topicName = remaining.front();
    }

    //
    // Retrieve the topic.
    //
    IceStorm::TopicPrx topic;
    try
    {
        topic = manager->retrieve(topicName);
    }
    catch(const IceStorm::NoSuchTopic&)
    {
        try
        {
            topic = manager->create(topicName);
        }
        catch(const IceStorm::TopicExists&)
        {
            cerr << appName() << ": temporary failure. try again." << endl;
            return EXIT_FAILURE;
        }
    }

    //
    // Get the topic's publisher object, and create a Clock proxy with
    // the mode specified as an argument of this application.
    //
    Ice::ObjectPrx publisher = topic->getPublisher();
    int optsSet = 0;
    if(opts.isSet("datagram"))
    {
        publisher = publisher->ice_datagram();
        ++optsSet;
    }
    else if(opts.isSet("twoway"))
    {
        // Do nothing.
        ++optsSet;
    }
    else if(opts.isSet("oneway") || optsSet == 0)
    {
        publisher = publisher->ice_oneway();
        ++optsSet;
    }
    if(optsSet != 1)
    {
        usage(appName());
        return EXIT_FAILURE;
    }
    ClockPrx clock = ClockPrx::uncheckedCast(publisher);

    cout << "publishing tick events. Press ^C to terminate the application." << endl;
    try
    {
        while(true)
        {
            clock->tick(IceUtil::Time::now().toDateTime());
            IceUtil::ThreadControl::sleep(IceUtil::Time::seconds(1));
        }
    }
    catch(const Ice::CommunicatorDestroyedException&)
    {
        // Ignore
    }

    return EXIT_SUCCESS;
}