server.cpp

来自「这是广泛使用的通信开源项目,对于大容量,高并发的通讯要求完全能够胜任,他广泛可用」· C++ 代码 · 共 788 行 · 第 1/2 页

CPP
788
字号
// server.cpp,v 1.6 2003/11/22 23:21:31 parsons Exp

// ============================================================================
//
// = LIBRARY
//    TAO/examples/Advanced/ch_18
//
// = FILENAME
//    server.cpp
//
// = AUTHORS
//   Source code used in TAO has been modified and adapted from the
//   code provided in the book, "Advanced CORBA Programming with C++"
//   by Michi Henning and Steve Vinoski. Copyright
//   1999. Addison-Wesley, Reading, MA.  Used with permission of
//   Addison-Wesley.
//
//   Modified for TAO by Mike Moran <mm4@cs.wustl.edu>
//
// ============================================================================

#include "server.h"
#include <algorithm>
#include "icp.h"
#include <orbsvcs/CosNamingC.h>
#include <strstream>
#include <iostream>
#include <fstream>

const char * Controller_oid = "Controller";

//----------------------------------------------------------------

template<class T>
typename T::_ptr_type
resolve_init (CORBA::ORB_ptr orb, const char * id)
{
  CORBA::Object_var obj;
  try {
    obj = orb->resolve_initial_references (id);
  }
  catch (const CORBA::ORB::InvalidName &) {
    throw;
  }
  catch (const CORBA::Exception & e) {
    cerr << "Cannot get initial reference for "
         << id << ": " << e << endl;
    throw 0;
  }
  assert (!CORBA::is_nil (obj.in ()));

  typename T::_var_type ref;
  try {
    ref = T::_narrow (obj.in ());
  }
  catch (const CORBA::Exception & e) {
    cerr << "Cannot narrow reference for "
         << id << ": " << e << endl;
    throw 0;
  }
  if (CORBA::is_nil (ref.in ())) {
    cerr << "Incorrect type of reference for "
         << id << endl;
    throw 0;
  }
  return ref._retn ();
}

//----------------------------------------------------------------

// Generic ostream inserter for exceptions. Inserts the exception
// name, if available, and the repository ID otherwise.

#if 0   // This inserter is not needed for TAO.

static ostream &
operator<< (ostream & os, const CORBA::Exception & e)
{
  CORBA::Any tmp;
  tmp <<= e;

  CORBA::TypeCode_var tc = tmp.type ();
  const char * p = tc->name ();
  if (*p != '\0')
    os << p;
  else
    os << tc->id ();
  return os;
}

#endif

//----------------------------------------------------------------

// Helper function to create object references.

static CCS::Thermometer_ptr
make_dref (PortableServer::POA_ptr poa, CCS::AssetType anum)
{
  // Convert asset number to OID.
  ostrstream ostr;
  ostr << anum << ends;
  char * anum_str = ostr.str ();
  PortableServer::ObjectId_var oid
    = PortableServer::string_to_ObjectId (anum_str);
  delete[] anum_str;

  // Look at the model via the network to determine
  // the repository ID.
  char buf[32];
  assert (ICP_get (anum, "model", buf, sizeof (buf)) == 0);
  const char * rep_id = strcmp (buf, "Sens-A-Temp") == 0
    ? "IDL:acme.com/CCS/Thermometer:1.0"
    : "IDL:acme.com/CCS/Thermostat:1.0";

  // Make a new reference.
  CORBA::Object_var obj
    = poa->create_reference_with_id (oid.in (), rep_id);
  return CCS::Thermometer::_narrow (obj.in ());
}

//----------------------------------------------------------------

Controller_impl * Thermometer_impl::m_ctrl;     // static member

// Helper function to read the model string from a device.

CCS::ModelType
Thermometer_impl::
get_model ()
{
  char buf[32];
  assert (ICP_get (m_anum, "model", buf, sizeof (buf)) == 0);
  return CORBA::string_dup (buf);
}

// Helper function to read the temperature from a device.

CCS::TempType
Thermometer_impl::
get_temp ()
{
  short temp;
  assert (ICP_get (m_anum, "temperature", &temp, sizeof (temp)) == 0);
  return temp;
}

// Helper function to read the location from a device.

CCS::LocType
Thermometer_impl::
get_loc ()
{
  char buf[32];
  assert (ICP_get (m_anum, "location", buf, sizeof (buf)) == 0);
  return CORBA::string_dup (buf);
}

// Helper function to set the location of a device.

void
Thermometer_impl::
set_loc (const char * loc)
{
  assert (ICP_set (m_anum, "location", loc) == 0);
}

// Constructor.

Thermometer_impl::
Thermometer_impl (CCS::AssetType anum) : m_anum (anum)
{
  m_ctrl->add_impl (anum, this);   // Add self to controller's set
}

// Destructor.

Thermometer_impl::
~Thermometer_impl ()
{
  if (m_ctrl->exists (m_anum))
    m_ctrl->add_impl (m_anum, 0);    // Clear servant pointer
}

// IDL model attribute.

CCS::ModelType
Thermometer_impl::
model () throw (CORBA::SystemException)
{
  return get_model ();
}

// IDL asset_num attribute.

CCS::AssetType
Thermometer_impl::
asset_num () throw (CORBA::SystemException)
{
  return m_anum;
}

// IDL temperature attribute.

CCS::TempType
Thermometer_impl::
temperature () throw (CORBA::SystemException)
{
  return get_temp ();
}

// IDL location attribute accessor.

CCS::LocType
Thermometer_impl::
location () throw (CORBA::SystemException)
{
  return get_loc ();
}

// IDL remove operation.

void
Thermometer_impl::
remove () throw (CORBA::SystemException)
{
  m_ctrl->remove_impl (m_anum);
  assert (ICP_offline (m_anum) == 0);
  //delete this;
}

// IDL location attribute modifier.

void
Thermometer_impl::
location (const char *loc) throw (CORBA::SystemException)
{
  set_loc (loc);
}

//----------------------------------------------------------------

// Helper function to get a thermostat's nominal temperature.

CCS::TempType
Thermostat_impl::
get_nominal_temp ()
{
  short temp;
  assert (ICP_get (m_anum, "nominal_temp", &temp, sizeof (temp)) == 0);
  return temp;
}

// Helper function to set a thermostat's nominal temperature.

CCS::TempType
Thermostat_impl::
set_nominal_temp (CCS::TempType new_temp)
throw (CCS::Thermostat::BadTemp)
{
  short old_temp;

  // We need to return the previous nominal temperature,
  // so we first read the current nominal temperature before
  // changing it.
  assert (
          ICP_get (
                   m_anum, "nominal_temp", &old_temp, sizeof (old_temp)
                   ) == 0
          );

  // Now set the nominal temperature to the new value.
  if (ICP_set (m_anum, "nominal_temp", &new_temp) != 0) {

    // If ICP_set () failed, read this thermostat's minimum
    // and maximum so we can initialize the BadTemp exception.
    CCS::Thermostat::BtData btd;
    ICP_get (
             m_anum, "MIN_TEMP",
             &btd.min_permitted, sizeof (btd.min_permitted)
             );
    ICP_get (
             m_anum, "MAX_TEMP",
             &btd.max_permitted, sizeof (btd.max_permitted)
             );
    btd.requested = new_temp;
    btd.error_msg = CORBA::string_dup (
                                       new_temp > btd.max_permitted ? "Too hot" : "Too cold"
                                       );
    throw CCS::Thermostat::BadTemp (btd);
  }
  return old_temp;
}

// Constructor.

Thermostat_impl::
Thermostat_impl (CCS::AssetType anum) : Thermometer_impl (anum)
{
  // Intentionally empty.
}

// Destructor.

Thermostat_impl::
~Thermostat_impl ()
{
  // Intentionally empty.
}

// IDL get_nominal operation.

CCS::TempType
Thermostat_impl::
get_nominal () throw (CORBA::SystemException)
{
  return get_nominal_temp ();
}

// IDL set_nominal operation.

CCS::TempType
Thermostat_impl::
set_nominal (CCS::TempType new_temp)
throw (CORBA::SystemException, CCS::Thermostat::BadTemp)
{
  return set_nominal_temp (new_temp);
}

//----------------------------------------------------------------

// Helper function to add an entry to the asset map.

void
Controller_impl::
add_impl (CCS::AssetType anum, Thermometer_impl * tip)
{
  m_assets[anum] = tip;
}

// Helper function to remove an entry from the asset map.

void
Controller_impl::
remove_impl (CCS::AssetType anum)
{
    m_assets.erase (anum);
}

// Helper function to locate a servant in the asset map.

bool
Controller_impl::
exists (CCS::AssetType anum)
{
    return m_assets.find (anum) != m_assets.end ();
}

// Constructor

Controller_impl::
Controller_impl (
    PortableServer::POA_ptr poa,
    const char *            asset_file
) throw (int) : m_poa (PortableServer::POA::_duplicate (poa)),
               m_asset_file (asset_file)
{
    fstream afile (m_asset_file.in (), ios::in|ios::out, 0666);
    if (!afile) {
        cerr << "Cannot open " << m_asset_file.in () << endl;
        throw 0;
    }
    CCS::AssetType anum;
    while (afile >> anum)
        m_assets[anum] = 0;
    //afile.close ();
    //if (!afile) {
    //    cerr << "Cannot close " << m_asset_file << endl;
    //    throw 0;
    //}
}

// Destructor

Controller_impl::
~Controller_impl ()
{
    // Write out the current set of asset numbers
    // and clean up all servant instances.
    ofstream afile (m_asset_file.in ());
    if (!afile) {
        cerr << "Cannot open " << m_asset_file.in () << endl;
        assert (0);
    }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?