Our weather measurement subscriber implementation takes the following steps:
TopicManager
. This is the primary IceStorm object, used by both publishers and subscribers.Monitor
servant.Monitor
servant and activate it with the object adapter.Weather
topic.report
messages until shutdown.Weather
topic.We present monitor implementations in C++ and Java below.
On this page:
Our C++ monitor implementation begins by including the necessary header files. The interesting ones are IceStorm/IceStorm.h
, which is generated from the IceStorm Slice definitions, and Monitor.h
, containing the generated code for our monitor definitions:
{zcode:cpp} #include <Ice/Ice.h> #include <IceStorm/IceStorm.h> #include <Monitor.h> using namespace std; class MonitorI : virtual public Monitor { public: virtual void report(const Measurement& m, const Ice::Current&) { cout << "Measurement report:" << endl << " Tower: " << m.tower << endl << " W Spd: " << m.windSpeed << endl << " W Dir: " << m.windDirection << endl << " Temp: " << m.temperature << endl << endl; } }; int main(int argc, char* argv[]) { ... Ice::ObjectPrx obj = communicator->stringToProxy("IceStorm/TopicManager:tcp -p 9999"); IceStorm::TopicManagerPrx topicManager = IceStorm::TopicManagerPrx::checkedCast(obj); Ice::ObjectAdapterPtr adapter = communicator->createObjectAdapter("MonitorAdapter"); MonitorPtr monitor = new MonitorI; Ice::ObjectPrx proxy = adapter->addWithUUID(monitor)->ice_oneway(); IceStorm::TopicPrx topic; try { topic = topicManager->retrieve("Weather"); IceStorm::QoS qos; topic->subscribeAndGetPublisher(qos, proxy); } catch (const IceStorm::NoSuchTopic&) { // Error! No topic found! ... } adapter->activate(); communicator->waitForShutdown(); topic->unsubscribe(proxy); ... } {zcode} |
Our implementation of the Monitor
servant is currently quite simple. A real implementation might update a graphical display, or incorporate the measurements into an ongoing calculation.
{zcode:cpp} class MonitorI : virtual public Monitor { public: virtual void report(const Measurement& m, const Ice::Current&) { cout << "Measurement report:" << endl << " Tower: " << m.tower << endl << " W Spd: " << m.windSpeed << endl << " W Dir: " << m.windDirection << endl << " Temp: " << m.temperature << endl << endl; } }; {zcode} |
After obtaining a proxy for the topic manager, the program creates an object adapter, instantiates the Monitor
servant and activates it:
{zcode:cpp} Ice::ObjectAdapterPtr adapter = communicator->createObjectAdapter("MonitorAdapter"); MonitorPtr monitor = new MonitorI; Ice::ObjectPrx proxy = adapter->addWithUUID(monitor)->ice_oneway(); {zcode} |
Note that the code creates a oneway proxy for the Monitor
servant. This is for efficiency reasons: by subscribing with a oneway proxy, IceStorm will deliver events to the subscriber via oneway messages, instead of via twoway messages.
Next, the monitor subscribes to the topic:
{zcode:cpp} IceStorm::TopicPrx topic; try { topic = topicManager->retrieve("Weather"); IceStorm::QoS qos; topic->subscribeAndGetPublisher(qos, proxy); } catch (const IceStorm::NoSuchTopic&) { // Error! No topic found! ... } {zcode} |
Finally, the monitor activates its object adapter and waits to be shutdown. After waitForShutdown
returns, the monitor cleans up by unsubscribing from the topic:
{zcode:cpp} adapter->activate(); communicator->waitForShutdown(); topic->unsubscribe(proxy); {zcode} |
The Java implementation of the monitor is shown below:
{zcode:java} class MonitorI extends _MonitorDisp { public void report(Measurement m, Ice.Current curr) { System.out.println( "Measurement report:\n" + " Tower: " + m.tower + "\n" + " W Spd: " + m.windSpeed + "\n" + " W Dir: " + m.windDirection + "\n" + " Temp: " + m.temperature + "\n"); } } public static void main(String[] args) { ... Ice.ObjectPrx obj = communicator.stringToProxy("IceStorm/TopicManager:tcp -p 9999"); IceStorm.TopicManagerPrx topicManager = IceStorm.TopicManagerPrxHelper.checkedCast(obj); Ice.ObjectAdapterPtr adapter = communicator.createObjectAdapter("MonitorAdapter"); Monitor monitor = new MonitorI(); Ice.ObjectPrx proxy = adapter.addWithUUID(monitor).ice_oneway(); IceStorm.TopicPrx topic = null; try { topic = topicManager.retrieve("Weather"); java.util.Map qos = null; topic.subscribeAndGetPublisher(qos, proxy); } catch (IceStorm.NoSuchTopic ex) { // Error! No topic found! ... } adapter.activate(); communicator.waitForShutdown(); topic.unsubscribe(proxy); ... } {zcode} |
Our implementation of the Monitor
servant is currently quite simple. A real implementation might update a graphical display, or incorporate the measurements into an ongoing calculation.
{zcode:java} class MonitorI extends _MonitorDisp { public void report(Measurement m, Ice.Current curr) { System.out.println( "Measurement report:\n" + " Tower: " + m.tower + "\n" + " W Spd: " + m.windSpeed + "\n" + " W Dir: " + m.windDirection + "\n" + " Temp: " + m.temperature + "\n"); } } {zcode} |
After obtaining a proxy for the topic manager, the program creates an object adapter, instantiates the Monitor
servant and activates it:
{zcode:java} Monitor monitor = new MonitorI(); Ice.ObjectPrx proxy = adapter.addWithUUID(monitor).ice_oneway(); {zcode} |
Note that the code creates a oneway proxy for the Monitor
servant. This is for efficiency reasons: by subscribing with a oneway proxy, IceStorm will deliver events to the subscriber via oneway messages, instead of via twoway messages.
Next, the monitor subscribes to the topic:
{zcode:java} IceStorm.TopicPrx topic = null; try { topic = topicManager.retrieve("Weather"); java.util.Map qos = null; topic.subscribeAndGetPublisher(qos, proxy); } catch (IceStorm.NoSuchTopic ex) { // Error! No topic found! ... } {zcode} |
Finally, the monitor activates its object adapter and waits to be shutdown. After waitForShutdown
returns, the monitor cleans up by unsubscribing from the topic:
{zcode:java} adapter.activate(); communicator.waitForShutdown(); topic.unsubscribe(proxy); {zcode} |