详解CORBA事件服务实现(作者:熊俊) CORBA事件服务通过对事件(由对象产生并且传送给其他对象)封装而提供了基本的消息传递功能,在事件被产生之后,CORBA事件服务是将事件从事件提供者对象传送给事件消费者对象这样一种机制。而且事件服务允许对象动态地注册或注销他们感兴趣的特定事件,事件服务在相互不很了解的对象之间建立起一条宽松耦合的通信信道。事件耦合程度比远程过程调用要松,但比面向消息的中间件(MOM)要紧。 有两种事件数据传送模型: ·推push 模型: 在推模型中,事件的提供者起带头作用,发起事件的传送; ·拉pull 模型: 在拉模型中,事件的消费者起带头作用,向提供者请求事件数据。 事件信道(event channel)是一个既是事件提供者又是事件消费者的插入对象,它允许多个事件提供者和多个事件消费者异步地通信而不需要相互了解。事件信道又是一个标准的CORBA对象,驻留在对象请求中介上,断开提供者和消费者的通信。 事件信道利用代理(proxy)对象撤消时间的提供者和消费者。提供者和消费者不是直接交互作用,而是从事件信道那里获得代理对象,让代理对象在将来的事件交换中代表自己。提供者获得一个消费者代理,而消费者获得一个提供者代理。事件信道通过这些代理对象代理事件的交换。 事件信道同时支持推和拉两种事件传送模型 ·对于推模型: 事件提供者发出一个调用,调用事件信道对象上的push方法,事件信道接着把数据推给消费者对象。消费者可以通过调用事件信道上的方法disconnect_push_consumer来停止接受事件,也可以调用事件信道上的connect_push_consumer方法来注册感兴趣的事件类型。 ·对于拉模型: 事件消费者发出一个调用,调用事件信道对象上的pull方法,事件信道接着把数据从提供者那里拉回来。利用try_pull方法,消费者可以周期性地轮询事件。通过调用事件信道上的disconnect_pull_ supplier方法,提供者可以停止接受要求提供事件的请求,提供者也可以调用事件信道上的add_pull_supplier方法,注册其对象标记,提供其服务。 我们可以通过理解CORBA事件序列的上下文来理解CORBA事件服务体系结构。 推模型 如图所示的Push事件脚本显示了一个推提供者通过事件信道向一个推消费者发送事件的简要过程。 1.对于一个推模型的推提供者来讲,基本的事件序列如下: (1)绑定到ORB和事件信道上: org.omg.CORBA.ORB orb= org.omg.CORBA.ORB.init(agrs,null); EventChannel eventChannel= EventChannelHelper.bin(orb); (2) 从事件信道中获取一个推消费者代理: SupplierAdmin admin= eventChannel.for_suppliers(); // 对应Push事件脚本的第一步 ProxyPushConsumer pushConsumer = admin .obtain_push_consumer(); // 对应图中Push事件脚本的第二步 (3) 创建一个推提供者: MySupplier pushSupplier=new MySupplier(); (4)将提供者连接到事件信道: pushConsumer.connect_push_supplier(pushSupplier);//对应图中Push事件脚本的第三步 (5) 创建一个CORBA消息: HelloImplementation msg=new HelloImplementation() (6)利用CORBA消息创建一个Any事件对象: Org.omg.CORBA.Any pushMessage=orb.create_any(); PushMessage.insert_Object(msg); (7) 将消息推给消费者: pushConsumer.push(pushMessage); // 对应图中Push事件脚本的第七步 2. 对于一个推模型的推消费者来讲,基本的事件序列如下: (1)绑定到ORB和事件信道上: org.omg.CORBA.ORB orb= org.omg.CORBA.ORB.init(agrs, null); EventChannel eventChannel= EventChannelHelper.bin(orb); (2) 从事件信道中获取一个推提供者代理: ConsumerAdmin admin= eventChannel.for_consumers();// 对应图中Push事件脚本的第四步 ProxyPushSupplier pushSupplier = admin .obtain_push_supplier(); // 对应图中Push事件脚本的第五步 (3) 创建一个推消费者: MyConsumer pushConsumer=new MyConsumer (); (4) 将消费者连接到事件信道: pushSupplier.connect_push_consumer(pushConsumer); // 对应图中Push事件脚本的第六步 (5) 在一个 push()实现中被接收: public void push(Any pushMsg){ // 对应图中Push事件脚本的第七步 org.omg.CORBA.Object object=pushMsg.extract_Object(); Hello msg=HelloHeper.narrow(object); } 拉模型 1.对于一个拉模型的拉提供者来讲,基本的事件序列如下: (1) 绑定到ORB和事件信道上: org.omg.CORBA.ORB orb= org.omg.CORBA.ORB.init(agrs, null); EventChannel eventChannel= EventChannelHelper.bin(orb); (2) 事件信道中获取一个拉消费者代理: SupplierAdmin admin= eventChannel.for_suppliers(); ProxyPullConsumer pullConsumer = admin .obtain_pull_consumer(); (3) 创建一个拉提供者: MySupplier pullSupplier=new MySupplier(); (4) 将提供者连接到事件信道: pullConsumer.connect_pull_supplier(pullSupplier); (5) 为消费者提供一个pull()接口用于拉消息: public org.omg.CORBA.Any pull() { org.omg.OCRBA.Any pullMsg=org.create_any(); HelloImplementation msg=new HelloImplementation(); pullMsg.insert_Object(msg); ruturn pullMsg; } (6) 为消费者设计一个try_pull()接口,实现只有当一个消息可用时它才会拉消息的功能: public Org.omg.CORBA.Any try_pull(org.omg.CORBA.BooleanHolder isAvail) { } 2.对于一个拉模型的拉消费者来讲,基本的事件序列如下: (1) 绑定到ORB和事件信道上: org.omg.CORBA.ORB orb= org.omg.CORBA.ORB.init(agrs, null); EventChannel eventChannel= EventChannelHelper.bin(orb); (2) 从事件信道中获取一个拉提供者代理: ConsumerAdmin admin= eventChannel.for_consumers(); ProxyPullSupplier pullSupplier = admin .obtain_pull_supplier(); (3) 创建一个拉消费者: MyConsumer pullConsumer=new MyConsumer (); (4) 将消费者连接到事件信道: pullSupplier.connect_pull_consumer(pullConsumer); (5) 对拉提供者代理调用try_pull()接口或者pull()接口并且将它转换为消息类型: org.omg.CORBA.BooleanHolder hoder=new org.omg.CORBA.BooleanHolder(); org.omg.CORBA.Any pullMsg=pullSupplier.tyr_pull(holer); org.omg.CORBA.Object obj=pullMsg.extract_Object(); Hello hello=HelloHelper.narrow(obj); //转换为消息类型 图 Push事件脚本 总的来说,CORBA事件服务只是在CORBA中引入了一个最低限度的MOM通信,它之所以是最低的,是因为它不支持像MOM那样的消息优先级、过滤器、交易保护和接受确认等管理机制。尽管如此,CORBA事件服务为对象动态地注册或注销它们感兴趣的特定事件提供了一个框架,利用这个框架,提供者可以把事件推给(push)消费者,消费者可以从提供者那里拉(pull)事件数据,而且多个提供者和消费者可以在一个事件信道上异步通信。件数据,而且多个提供者和消费者可以在一个事件信道上异步通信。 |