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 + -
显示快捷键?