IceStorm发布订阅模式的实现

341 阅读1分钟

1.启动IceStrom服务

1.1编写config.icebox文件

IceBox.ServiceManager.Endpoints=tcp -h localhost -p 9998
IceBox.Service.IceStormDemo=IceStormService,37:createIceStorm --Ice.Config=config.service

1.2编写config.service文件

IceStormDemo.InstanceName=WeatherService
IceStormDemo.TopicManager.Endpoints=tcp -p 9999
IceStormDemo.Publish.Endpoints=tcp -p 10000
Freeze.DbEnv.IceStormDemo.DbHome=db

1.3运行命令:iceBox --Ice.Config=config.icebox

出现错误:

!! 07/26/20 15:15:55.148 icebox: error: exception while starting IceStorm service IceStormDemo:
   ..\..\..\IceUtil\FileUtil.cpp:302: ::IceUtil::FileLockException:
   could not lock file: `IceStormDemo/icedb.lock'
   syscall exception: 系统找不到指定的路径。

在这里插入图片描述 解决:在同一个目录下面添加一个文件夹:IceStormDemo 在这里插入图片描述 再次运行即可: 在这里插入图片描述

2 编写Slice接口

module DemoMonitor {
	struct Measurement
	{   
		string tower; 
		float windSpeed; 
		short windDirection; 
		float temperature;
	};

	interface Monitor
	{   
	    void report(Measurement m);
	};
};

3.使用slice2cpp.exe转换成.h和.cpp文件

4.把这个Monitor.h和Monitor.cpp拷贝到对应的项目下面。

5.发布者项目:

在这里插入图片描述

#include "Monitor.h"
#include <Ice/Ice.h>
#include <IceStorm/IceStorm.h>

int main(int argc, char *argv[]) {
	Ice::CommunicatorPtr communicator = Ice::initialize(argc, argv);
	//注意这里要用config.service中定义的instance名。
	Ice::ObjectPrx obj = communicator->stringToProxy("WeatherService/TopicManager:default -h localhost -p 9999");
	IceStorm::TopicManagerPrx topicManager = IceStorm::TopicManagerPrx::checkedCast(obj);
	IceStorm::TopicPrx topic;
	while (!topic) {
		try {
			topic = topicManager->retrieve("Weather");
		} catch (const IceStorm::NoSuchTopic&) {
			try {
				topic = topicManager->create("Weather");
			} catch (const IceStorm::TopicExists&) {
				// Another client created the topic.
			}
		}
	}
	//取得publisher对象的代理
	Ice::ObjectPrx pub = topic->getPublisher()->ice_oneway();
	DemoMonitor::MonitorPrx monitor = DemoMonitor::MonitorPrx::uncheckedCast(pub);
	while (true) {
		DemoMonitor::Measurement m ;
		m.temperature = 10.1f;
		m.tower = "中央气象台";
		m.windDirection = 1;
		m.windSpeed = 10;
		monitor->report(m);
		Sleep(1000);
	}
	
	return 0;
}

6.订阅者

在这里插入图片描述

#include "Monitor.h"
#include <Ice/Ice.h>
#include <IceStorm/IceStorm.h>

static int count = 0;

class MonitorI : virtual public DemoMonitor::Monitor {
public:
	virtual void report(const DemoMonitor::Measurement& m, const Ice::Current&) {
		std::cout << "气象报告:" << ++ count << std::endl
			<< "  来源: " << m.tower << std::endl
			<< "  风速: " << m.windSpeed << std::endl
			<< "  风向: " << m.windDirection << std::endl
			<< "  温度: " << m.temperature << std::endl
			<< std::endl;
	}
};


int main(int argc, char *argv[]) {

	Ice::CommunicatorPtr communicator = Ice::initialize(argc, argv);
	//注意这里要用config.service中定义的instance名。
	Ice::ObjectPrx obj = communicator->stringToProxy("WeatherService/TopicManager:default -h localhost -p 9999");
	IceStorm::TopicManagerPrx topicManager = IceStorm::TopicManagerPrx::checkedCast(obj);

	Ice::ObjectAdapterPtr adapter = communicator->createObjectAdapterWithEndpoints("MonitorAdapter", "default -h localhost -p 5438");

	DemoMonitor::MonitorPtr monitor = new MonitorI;
	Ice::ObjectPrx proxy = adapter->addWithUUID(monitor)->ice_oneway();
	adapter->activate();

	IceStorm::TopicPrx topic;
	try {
		topic = topicManager->retrieve("Weather");
		IceStorm::QoS qos;
		topic->subscribeAndGetPublisher(qos, proxy);
	} catch (const IceStorm::NoSuchTopic&) {
		// Error! No topic found!
	}

	communicator->waitForShutdown();

	topic->unsubscribe(proxy);

	return 0;
}

7.运行发布者和订阅者

在这里插入图片描述

aaa