TAO教程之三:介绍-改进服务端,通过POA策略之显示激活和用户自定义对象ID

跟我从头学TAO编程系列(3) -- 通过实例学习CORBA核心概念 跟我从头学TAO编程系列 编写最简单的TAO应用程序 Stone Jiang 2005119@gmail.com http://www.ace-tao.org   本系列的第一篇我们学会了怎么下载和编译ACE,TAO,第二篇我们编写了最简单的TAO应用程序。这了节,我们通过第二篇的实例来学习CORBA的核心概念。   1.CORBA架构 CORBA的架构如下图: 2 阅读详情

3.介绍-改进服务端,通过POA策略之显示激活和用户自定义对象ID

介绍——改善服务端

在本节,我们将在之前提到的“简单服务器”之上进行改进。我们将会讨论如何使把POA策略赋给对象ID。

在先前的示例中,我们用了 Quoter_Stock_Factory_i 的两个域来表示两支股票。如果我们想创建上百支股票,那么这种方法就缺少扩展性。我们需要用某个集合来保持对股票对象的跟踪,比如为股票符号建立索引。一种解决办法是使用STL map或与之差不多的集合类,但这样明显太浪费了。毕意,ORB已经以对象ID为索引建立了对象的集合。如果仅能自己选择ID,那么我们的问题就能得已解决。一个好消息是:POA允许这样做;一个坏消息是我们必须创建子POA。那这是为什么呢?这是因为RootPOA的ID是被ORB分配了的,我们不想要与它们冲突。此外,创建一个独立的POA比管理它更容易,因为多个应用程序的组件可以获得它们自己的POA,它们能被视为私有的命字空间。

子POA的创建

如前所述,我们可以访问RootPOA:

   CORBA::Object_var poa_object =
      orb->resolve_initial_references ("RootPOA");
    PortableServer::POA_var poa =
      PortableServer::POA::_narrow (poa_object.in ());

现在我们为子POA创建策略。在这个应用场景下,我们想使用USER_ID策略,这样就可以把它赋自己的这些ID。我们还想使用 NO_IMPLICIT_ACTIVATION 策略,以便于对我们的POA有更多的控制。POA具有许多我们可以控制的策略,但我们在示例中只使用默认的策略。在$TAO_ROOT/examples/POA/目录下有许多示例演示了如何使用这些策略。

策略存储在序列中的,所以我们首先创建序列并初始化它的长度。

    CORBA::PolicyList policies (2);
    policies.length (2);

接下来我们创建策略:

    policies[0] =
      poa->create_id_assignment_policy (PortableServer::USER_ID);
    policies[1] =
      poa->create_implicit_activation_policy (PortableServer::NO_IMPLICIT_ACTIVATION);

再然后我们创建子POA:

    PortableServer::POA_var stock_factory_poa =
      poa->create_POA ("Stock_Factory_POA",
                       poa_manager.in (),
                       policies);

注意的是,我们与RootPOA共用了POA管理器,于是我们只需要用一个POA管理就可以控制这两个POA的状态。新的POA复制了策略,所以我们为了避免内存泄漏,所以需要销毁它们。

    for (CORBA::ULong i = 0; i != policies.length (); ++i)

    {
      policies[i]->destroy ();
    }

在子POA中激活对象

现在我们必须使用这个POA来激活股票对象了。为了使示例简化,我们假设我们可以从标准输入设备(stdin)中读入这些股票信息,比如这样:

   while (!std::cin.eof () && std::cin.peek () != EOF)

  {
      const int max_symbol_length = 8;
      char symbol[max_symbol_length];
      const int max_full_name_length = 64;
      char full_name[max_full_name_length];
      double price;
      std::cin.getline (symbol, max_symbol_length, '/n');
      std::cin.getline (full_name, max_full_name, '/n');
      std::cin >> price;
      std::cin.ignore (1, '/n');
      // The interesting stuff goes here!
    }

为每个符号、全称和价格的三元组中, 我们创建股票实现的对象:

     PortableServer::ServantBase_var servant =
        new Quoter_Stock_i (symbol, full_name, price);

ServantBase_var 充当的角色很象自动指针,在发生异常的情况下,它可以小心的管理对象的回收操作。这次我们不能使用_this() 来激活对象,这是因数我们要想创建自己对象ID:

      PortableServer::ObjectId_var oid =
        PortableServer::string_to_ObjectId (symbol);

然后我们通过id来激活对象:

  stock_factory_poa->activate_object_with_id (oid.in (),
                                                  servant.in ());

请小心,不要在这些对象上调用_this(),如果这样就会在RootPOA中激活它们,被激活了两次!虽然在不同的POA中(甚于有时还在同一个POA中)多次激活一个对象是完全合法的,它是在现在的应用情景中我们并不需要这样做。

修改Stock Factory

现在我们必须实现Stock Factory的不同版本。我们传一个子POA的引用到构造函数中并维护这个引用:

class Quoter_Stock_Factory_i : public POA_Quoter::Stock_Factory
{
public:
  Quoter_Stock_Factory (PortableServer::POA_ptr stock_factory_poa)
    : stock_factory_poa_ (PortableServer::POA::_duplicate (stock_factory_poa))
  {}
  Quoter::Stock_ptr get_stock (const char *symbol)
    throw (Quoter::Invalid_Stock_Symbol);
private:
  PortableServer::POA_var stock_factory_poa_;
};

注意,我们复制了POA,这样才遵从惯用的CORBA对输入参数的内存管理规则。尽管构造函数并不是CORBA操作,这样做我们可以把这个规则使用得更广泛,如果我们坚持使用CORBA这套规则时可以减少误解。

get_stock 操作的实现更为有趣。首先我们依据符号创建对象的ID:

Quoter::Stock_ptr
Quoter_Stock_Factory_i::get_stock (const char *symbol)
    throw (Quoter::Invalid_Stock_Symbol)
{
  PortableServer::ObjectId_var oid =
    PortableServer::string_to_ObjectId (symbol);

接下来在POA中查找对象的ID:

try {
    CORBA::Object_var tmp =
      this->stock_factory_poa_->id_to_reference (oid.in ());

最后将对象的引用narrow到正常的类型并返回它:

     return Quoter::Stock::_narrow (tmp.in ());
  }

要是符号无效,POA就找不对正确的对象ID,只好抛出异常:

  catch (PortableServer::POA::ObjectNotActive &) {
    throw Quoter::Invalid_Stock_Symbol ();
  }
}

股票对象的内存管理

迄今为止,我们还尚为讨论伺服代码(servants)的内存管理问题。现在是讨论它的最好时机了,因为股票对象已完全授控于POA了。POA为伺服代码提供了引用计数。你并不需要使用引用计数,如果你遵从了这一点,那绝大多数的内存管理就相当的简单了。那为什么不是所有的时候都可以不使用引用计数呢?那是因为有的应用程序不需要它。举例来说,我们先前的简单服务不需要任何复杂的对象管理,于是所有的对象都是在栈(stack)上创建的。

如果想在POA中使用引用计数,你必须重载_add_ref() 和remove_ref() 这两个方法用来增加或减少引用的数目。 一旦数目回到0,你就可以安全的删除对象(但要记住,计数数目是从1开始的!)。

把这些方法实现为线程安全是一件繁琐的工作。为了减化这个工作,我们混合使用了PortableServer::RefCountServantBase 这个作为基类,像这样:

class Quoter_Stock_i
    :  public virtual POA_Quoter::Stock,
       public virtual PortableServer::RefCountServantBase
{
public:
  Quoter_Stock_i (const char *symbol,
                  const char *full_name,
                  CORBA::Double price);
  // as before
};

TAO中PortableServer::RefCountServantBase 的实现也是线程安全的,于是你可以用这个技术在你的多线程服务中动态的销毁对象。您简单的委托POA来控制,一旦所有线程调用了对象中止,当休眠该对象时,POA将会调用 _remove_ref(),这样如果这个对象还在使用中就不会被删除。也请记住如果你要使用对象请增加它的引用记数。

练习

从简单服务的文件作如下修改:

  • Stock_i.h: 使用引用计数控制伺服代码的内存管理。
  • Stock_Factory_i.h: Apply the changes described above to use a child POA with the appropriate policies.
  • Stock_Factory_i.cpp: Apply the changes described above to use a child POA with the appropriate policies.
  • server.cpp: Create the child POA, initialize the stock objects from the stdin, and create the right stock factory class.

你能够使用相同的Quoter.idl, Stock_i.cpp 和MPC 文件.

解决方案

在你的解决方案在同下面的文件作比较:

Does this solution scale when the number of stock symbols is in the thousands or millions? Find out about Servant Locators and Servant Activators in the POA!

Testing

有一个简单的输入文件可用. 你可以使用简单客户端来检查结果:

$ server < stock_list.txt > ior_file
$ client file://ior_file AAAA BBBB MSFT RHAT CCCC

也测试一下无效的符号!

More Reading

The Henning and Vinoski CORBA book discusses POA policies in detail. Likewise, the Schmidt and Vinoski columns in C++ Report also include several articles about the POA. Finally, the TAO distribution includes examples that illustrate how to use the POA policies.

TAO教程系列之一:用TAO创建股票报价系统 用TAO创建股票报价系统 Building a Stock Quoter with TAO- A Tutorial 本教程译自$(ACE_ROOT%)/TAO/ docs/tutorials/Quoter。由Stone Jiang试译。原文 revision history: date: 2007-11-05 by Stone Jiang 本教程是围绕一个单一的应用程序组织的,它允许客户 阅读详情

相关推荐

CORBA服务器端C++实现:从IDL映射到POA策略的深度解析

在分布式系统架构中,远程过程调用(RPC)是实现跨网络服务通信的基础技术,其核心原理是通过代理机制屏蔽底层网络细节,实现位置透明性。CORBA作为经典的分布式对象中间件标准,通过IDL接口定义语言实现语言中立性,而C++映射则是将抽象接口转化为可执行服务端组件的关键技术环节。从技术价值看,C++凭借其高性能和精细内存控制能力,成为构建高性能、高可靠性CORBA服务端的首选,尤其适用于金融交易、电信系统等对实时性要求苛刻的领域。具体到实现层面,IDL编译器生成的C++骨架代码与伺服对象实现构成了服务端核心,而

weixin_29174141的博客 247

TAO教程之四:改进服务端之通过POA策略实现持久化的对象引用

改进服务端之通过POA策略实现持久化的对象引用 介绍-改进服务器 在本节中,我们将改进之前写的简单服务器(第二篇)。我们要利用POA策略来创建具有持久化对象引用的对象。 在创建POA时为其指定策略可以用于控制POA的特性。POA的策回略都具有相同的形式:在创建时使用枚举类型为它指定值。在我们的示例中,我们要使用LifeSpanPolicy这个策略控制对象引用的生命期和创建它的对象的POA的生

TAO工作室Stone Jiang的专栏 3529

Nestjs框架: 集成 Prisma

NestJS官方文档提供了两种数据库相关的内容:Techniques下的数据库板块和Recipes下的具体数据库集成方案。本文以Prisma为例,演示了如何集成Prisma到NestJS项目中。首先创建NestJS项目并安装Prisma,配置MySQL数据库连接。通过Prisma CLI初始化项目、定义数据模型并生成迁移文件。接着创建Prisma模块和服务,配置Prisma客户端连接数据库。最后在控制器中注入PrismaService实现数据查询。整个过程包含了Docker启动MySQL、Prisma模型定

Wang的专栏 1295

CORBA Programming with TAO - 5.Hello World(简单实例)

CORBA Programming with TAO - 5.Hello World(简单实例)摘要:前面对CORBA编程的基础知识进行了简单介绍,本篇中,我们将实例讲解如何利用TAO中进行CORBA编程。一、编写IDL1、建一个空的Solution,然后在该Solution目录下新建一个名为idl的Win32 Static Library工程(对于一般的TAO工程,无需单独为id

大卫的思维空间 5980

3GPP协议解读_物理层系列(一)_物理层协议怎么看?

5G NR相关协议一般都在38系列,点进去以后可以看到,38.2xx系列为物理层相关协议,为了掌握物理层相关知识,应该怎么看协议呢?我建议从38.201读起,对38.2xx系列协议有一个整体的把握。

JCMLSY的博客 1329

人工智能顶会投稿指南:CCF-A类会议ACL、ICML、NeurIPS、ICLR的投稿周期与影响力解析

本文详细解析了CCF-A类会议ACL、ICML、NeurIPS、ICLR的投稿周期与影响力,涵盖各会议的投稿时间线、评审特点及录用率。ACL注重自然语言处理,ICML强调机器学习理论,NeurIPS覆盖神经信息处理,ICLR聚焦表征学习。文章还提供了实战投稿策略,帮助研究者提升投稿成功率。

weixin_29211309的博客 3353

omniORB笔记

omniORB笔记12007-08-30 16:33资料来源:omniORB4.07库自带我的英文很差,要翻译和理解doc下一堆英文很有挑战性。一些简单说明:omniORB是CORBA(公用对象代理体系架构)的一种开发库,主要适用C++和python。CORBA实现了异构系统的异种语言软体合并、协作。CORBA的大体实现方式:使用IDL实现与其它编程语言的映射;

xjh_Love_paopao的专栏 1825

企业AI Agent审计与合规:从日志留存到网络联动的完整落地指南

审计日志是企业安全与合规体系的基石,尤其在AI Agent大规模接入业务后,如何完整记录其行为链成为新的挑战。从日志留存180天到PCI DSS合规要求,审计体系需要覆盖会话、推理、工具调用、数据访问等关键环节,并结合不可篡改的存储设计,确保证据链可信。同时,借鉴上网行为管理设备对应用行为控制审计的思路,以及Kismet被动监测网络流量的方法论,将网络侧审计与应用侧日志交叉验证,能有效发现越权和异常行为。本文从日志采集、全链路追踪、基线预警到多租户隔离,系统梳理了AI Agent审计与合规落地的关键路径,帮

weixin_32234493的博客 269

TAO教程之三:介绍-改进服务端,通过POA策略之显示激活和用户自定义对象ID...

3.介绍-改进服务端,通过POA策略之显示激活和用户自定义对象ID 介绍——改善服务端 在本节,我们将在之前提到的“简单服务器”之上进行改进。我们将会讨论如何使把POA策略赋给对象ID。 在先前的示例中,我们用了 Quoter_Stock_Factory_i 的两个域来表示两支股票。如果我们想创建上百支股票,那么这种方法就缺少扩展性。我们需要用某个集合来保持对股票对象的跟踪,比如为股票符号建...

pleasetojava 154

FAST-LIO2实战:如何在无人机上部署并实现厘米级定位(附ROS配置全流程)

本文详细介绍了如何在无人机上部署FAST-LIO2激光雷达惯性里程计系统,以实现厘米级精确定位。内容涵盖从硬件选型(如激光雷达与机载计算机)、软件环境配置(ROS Noetic)、传感器标定,到FAST-LIO2参数调优、与PX4飞控集成以及实际飞行测试的全流程。重点解决了实时定位中的外参标定、数据同步等关键问题,为无人机在无GPS或复杂光照环境下提供稳定可靠的定位解决方案。

weixin_29062865的博客 251

粒子群算法实战:用Matlab解决旅行商问题(TSP)的完整代码解析

本文提供了使用粒子群算法解决旅行商问题的完整Matlab实战指南。通过将连续空间的粒子群算法进行离散化改造,采用基于交换序的策略来更新粒子位置与速度,并给出了从问题定义、数据结构设计、核心函数实现到主迭代循环的详细代码解析。文章还探讨了参数调优、性能优化及处理复杂TSP变体的进阶思路,为物流规划、路径优化等领域的工程应用提供了可直接复用的解决方案。

m2n3o4p5的博客 350

TAO教程之八:按需激活

按需激活 伺服(Servant)管理器 在先前的示例中,我们对使用同步方法调用的简单客户端进行了扩展,用于处理异步请求:通过使用回复处理器的异步方向调用。 在应用程序中有许多对象,没有必要在同时激活所有的对象,并且,如果同时激活所有对象会导致占用过多的内存或过多的数据库查询。为了解决这类应用程序面临的问题,POA提供了一个选项让应用程序提供伺服管理器,伺服管理器可以在每一个请求上动态的提供

TAO工作室Stone Jiang的专栏 2055

跨 Agent 语义沟通机制构建:共享知识图谱与语义对齐方法

在具身智能与多智能体系统协同日益复杂化的背景下,跨 Agent 的语义沟通能力成为任务完成效率和系统鲁棒性提升的关键技术路径。本文系统分析了当前业界在共享知识图谱、语义嵌入对齐、语义意图建模与跨模态语义通信协议设计方面的实践经验,深入讲解如何在 Habitat-MARL 与 Isaac-MARL 等平台中,基于实体-关系结构、语义分布表示与任务上下文,构建具备理解、共享、协作能力的多 Agent 语义系统。文章以工程实战为主,覆盖图谱构建、语义嵌入同步、对齐模型部署、通信接口集成等多个核心模块,结合真实应用

努力分享一些人工智能、计算机视觉、影像等相关的知识干货! 1293

(ORBA与分布式应用)TAO股票报价系统例用

这 篇教程从简单的客户程序及服务程序到剖析TAO的高级特性而逐步构建,这些高级特性包括了:asynchronous method invocation,reliable oneways, real-time Evnet Service, Interoperable Naming Service等等。

Tech is Online(物联网技术传播) 2722

【Python3教程】Python3高级篇之uWSGI 安装配置

本文介绍了在Python 3环境中安装和配置uWSGI的完整流程,涵盖基本安装、Flask/Django应用部署、Nginx集成以及systemd管理等关键环节。主要内容包括:uWSGI的安装前提条件,创建简单WSGI应用,编写uWSGI配置文件(.ini格式),与Nginx配合实现生产环境部署,以及使用systemd实现服务管理。文章还提供了常见Web框架(Flask、Django)的部署示例和高级配置建议,如负载均衡、HTTPS设置等。最后列出了权限、端口占用等常见问题的解决方案,为开发者提供了一套完整

No8g攻城狮的博客 438

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

从Corba接口中取到的数据填充FastReport报表

环境:编程工具:Borland C++ Builder 6.0操作系统:windows 2000应用软件:FastReport5.2破解版1.安装FastReport如安装到c:/program files/fastreports2.在bcb 6中使用FastReport(本过程从RastReport中抄写)l         复制c:/program files/fastreports/ fas

Johnny的专栏 961

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

C++虚函数(4) - 静态函数能否为虚函数

C++虚函数(4) - 静态函数能否为虚函数

1万+

CORBA之TAO的第一个hello_world C++

编译以后就让我们来编译一个hello_world吧 一、IDL文件定义     新建一个后缀为hello.idl文件类型的空文件,在文件中定义接口: /// 20150726 for tao module Test { interface Hello {     string get_hello (); }; }; 二、IDL文件生成     用vc2008的c

xinqingwuji的博客 2386

POA和纽带机制

我们继续了解CORBA中间件的相关知识,本篇博客我们讲解可移植对象适配器(POA)和纽带机制。 CORBA中间件的另一优势就是提供了灵活的服务端模型,该模型基于可移植对象适配器体系结构,可以帮助开发人员有效管理复杂的服务端程序。在了解POA之前我们先明白什么是CORBA对象和伺服对象,他们之间的关系是什么。     CORBA对象和伺服对象:两者之间的关系就像是面向对象中类和对象的关系,C

致力于顶级java全栈工程师 3085

使用Parity建立Proof-of-Authority (PoA) Ethereum Chain5分钟快速从无到有建立Ethereum联盟链

5分钟快速从无到有建立Ethereum联盟链 开发Ethereum Dapp的过程中,需要一个测试用的chain,之前是使用testrpc或直接连到Ethereum testnet (Ropsten),不过testrpc有各种坑需要处理,而Ropsten testnet则是需要同步与等待区块,相当的烦人。前几天看到Parity 1.5版以后支持建立Proof of Authority Chain

陈建慧程序人生 1万+

跟我学数据结构:(5) 基础知识的小结

TAO工作室Stone Jiang的专栏 1517
上一篇: TAO教程系列之二. 简介&mdash;&mdash;非常简单的服务端
下一篇: TAO教程之四:改进服务端之通过POA策略实现持久化的对象引用
Stone
博客等级 码龄21年 1715粉丝 158原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值