您的位置:首页 > 编程语言 > C语言/C++

Hands-on on VisiBroker5.1 for C++ and Java (2)

2009-06-16 21:50 465 查看
续前篇:Hands-on on VisiBroker5.1 for C++ and Java (1)

Chapter 3 Example2 : Efficiency Java vs. C++

As we explain how to write a CORBA compliant application exhaustively in Chapter 2, here in this chapter, we just give the source code, and some explanations will still be given in the form of comments.

3.1 The IDL file
module HelloApp
{
interface Hello
{
string sayHello1(in string name);
string sayHello2();
long add(in long op1, in long op2);
};
};

3.2 Client in Java
import java.util.*; //In order to get system time
public class HelloClient
{
public static void main(String[] args)
{
long i;
Date dbegin;
dbegin = new Date();

java.util.Date dend;

//initialize the ORB
org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args, null);

//get the servantID
byte[] servantID = "Helloo".getBytes();

//---added by Patrick
com.inprise.vbroker.CORBA.BindOptions bindOptions =
new com.inprise.vbroker.CORBA.BindOptions(false, true);

//locate the servant. give the full POA name and the servant ID
//HelloApp.Hello helloServant =
// HelloApp.HelloHelper.bind(orb, "/hello", servantID); //be replaced by following line
HelloApp.Hello helloServant =
HelloApp.HelloHelper.bind(orb, "/hello", servantID, "127.0.0.1", bindOptions);
//Please see Section 2 in Chapter 4 about the IP address

String name = args.length > 0 ? args[0] : "Patrick H. Huang";

int op1 = args.length > 1 ? Integer.parseInt(args[1]) : 0;
int op2 = args.length > 2 ? Integer.parseInt(args[2]) : 0;

System.out.println("Hello! " + helloServant.sayHello1(name) + ".");
System.out.println(helloServant.sayHello2());
System.out.println(op1 + " + " + op2 + " = " + helloServant.add(op1, op2));

dend = new Date();
i = (dend.getTime() - dbegin.getTime());
System.out.println(i + " millisecond elapsed!");
}
}

3.3 Implementation of Servant in Java
//HelloImpl.java
public class HelloImpl extends HelloApp.HelloPOA
{
static int i = 0;

public String sayHello1(String name)
{
i++;
System.out.println("***************** Be invoked for " + i + " times. *****************");
return name;
}

public String sayHello2()
{
return "My name is Patrick, it is really very nice to meet you!";
}

public int add(int op1, int op2)
{
return op1 + op2;
}
}

3.4 Server in Java
import org.omg.PortableServer.*;

public class HelloServer
{
public static void main(String[] args)
{
try
{
//initialize the ORB
org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args, null);

//get a reference to the root POA
POA rootPOA = POAHelper.narrow(orb.resolve_initial_references("RootPOA"));

//create policies for my persistent POA
org.omg.CORBA.Policy[] policies =
{
rootPOA.create_lifespan_policy(LifespanPolicyValue.PERSISTENT)
};

//create my POA
POA myPOA = rootPOA.create_POA("hello", rootPOA.the_POAManager(), policies);

//create the servant
HelloImpl helloServant = new HelloImpl();

//get the ID for the servant
byte[] helloServantID = "Helloo".getBytes();

//activate the servant with the servant ID on the above created POA
myPOA.activate_object_with_id(helloServantID, helloServant);

//activate the POA manager
rootPOA.the_POAManager().activate();
myPOA.the_POAManager().activate();
//wait for incoming requests

System.out.println("Waiting for requests...");
//orb.perform_work();
orb.run();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}

3.5 vbmake.bat
@echo off
rem Makefile

if "%1"=="" goto all
if "%1"=="clean" goto clean
goto usage

:all
echo Building the selfTraing/Hello application ...
call idl2java Hello.idl
vbjc HelloClient.java
vbjc HelloServer.java
goto end

:clean
if "%OS%"=="Windows_NT" goto nt
deltree /y HelloApp
del *.class
goto end
:nt
rd /s /q HelloApp
del /q *.class
goto end

:usage
echo Usage: vbmake [clean]

:end

3.6 Client in C++
#include "Hello_c.hh"
#include "corba.h" //在使用BindOptions结构时应包含 corba.h 文件
#include "time.h" // OK on Unix and Windows
#include "sys/timeb.h" // specifically for Windows

USE_STD_NS

int main(int argc, char* const* argv)
{
try
{
//time_t t1 = time(NULL); // will be OK on Unix and Windows
struct _timeb timebuffer1; // specifically for Windows
_ftime(&timebuffer1); // specifically for Windows

//initialize the ORB
CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);

//get the servant ID
PortableServer::ObjectId_var servantID = PortableServer::string_to_ObjectId("Helloo");

//locate the servant. give the full POA name and the servant ID
//HelloApp::Hello_var helloServant = HelloApp::Hello::_bind("/hello", servantID);

//the following line is added by Patrick to replace the the above line.
//advantage: will speed up to look for the osagent.
HelloApp::Hello_var helloServant =
HelloApp::Hello::_bind("/hello", servantID, "127.0.0.1", CORBA_Object::_default_bind_options(), orb);

const char* name = argc > 1 ? argv[1] : "Patrick";
long op1 = argc > 2 ? atol(argv[2]) : 0l;
long op2 = argc > 3 ? atol(argv[3]) : 0l;

cout << "Hello! " << helloServant->sayHello1(name) << "." << endl;
cout << helloServant->sayHello2() << endl;
cout << op1 << " + " << op2 << " = " << helloServant->add(op1, op2) << endl;

//time_t t2 = time(NULL);
struct _timeb timebuffer2; // specifically for Windows
_ftime(&timebuffer2); // specifically for Windows

cout << (timebuffer2.time - timebuffer1.time) * 1000 + timebuffer2.millitm - timebuffer1.millitm
<< " milliseconds elapsed." << endl;
}
catch(const CORBA::Exception& e)
{
cerr << e << endl;
return 1;
}
return 0;
}
/*
BindOptions Deprecated as of VisiBroker 4.x struct BindOptions 此结构用于指定 _bind 方法的选项,这在本手册的 “对象” 一节中加以描述。每个进程均有一个全局 BindOptions 结构,它用于未指定限制选项的所有 _bind 调用。您可以使用 Object::_default_bind_options 方法修改默认限制选项。 限制选项还可设置于特定对象,并在对象连接的使用期间一直有效。 包含文件 在使用此结构时应包含 corba.h 文件。 BindOptions 成员 CORBA::Boolean defer_bind; 如果设置为 TRUE,客户端与对象实施之间的连接将延迟至第一个客户端操作发布时建立;如果设置为 FALSE,_bind 方法应立即建立连接。 CORBA::Boolean enable_rebind; 如果设置为 TRUE 并且由于网络故障或其它错误而使连接断开,VisiBroker ORB 将试图重新建立合适对象实施的连接;如果设置为 FALSE,则不会试图重新建立客户端与对象实施的连接。 CORBA::Long max_bind_retries; 在 OAD 遇忙时,
此成员指定重试限制请求的次数。 CORBA::ULong send_timeout; 此方法指定客户端遇阻时等待发送操作请求的最大秒数。如果请求超时,则会引发 CORBA::NO_RESPONSE 违例并且销毁至服务器的连接。值 0 表示客户端阻塞时间无限制。 CORBA::ULong receive_timeout; 此方法指定客户端遇阻时等待响应操作请求的最大秒数。如果请求超时,则会引发 CORBA::NO_RESPONSE 违例并且销毁至服务器的连接。值 0 表示客户端阻塞时间无限制。 CORBA::ULong connection_timeout; 此成员指定客户端等待连接的最大秒数。如果超时,则会引发 CORBA::NO_IMPLEMENT 违例。默认值 0 表示连接使用默认系统超时设置。
*/

3.7 Implementation of Servant in C++
#include "Hello_s.hh"
#include "string.h"
#include <math.h>

USE_STD_NS

class HelloImpl : public virtual POA_HelloApp::Hello, public virtual PortableServer::RefCountServantBase
{
public:
char* sayHello1(const char* name)
{
/* char* str;
str = '/0';
str = (char*)strcat((char*)"Hello! ", name);
str = str + '/0';
return str;
*/
static CORBA::Long times = 0;
times++;
cout << "******************* Be invoked for " << times << " times. *******************" << endl;
return (char*)name;
}

char* sayHello2()
{
return "My name is Patrick, it is really very nice to meet you!";
}

CORBA::Long add(CORBA::Long oper1, CORBA::Long oper2)
{
return oper1 + oper2;
}
}; //do not forget this semicolon “;” ****** very important!

3.8 Server in C++
#include "HelloImpl.h"

USE_STD_NS

int main(int argc, char* const* argv)
{
try
{
//intialize the ORB
CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);

//get a reference to the root POA
CORBA::Object_var obj = orb->resolve_initial_references("RootPOA");
PortableServer::POA_var rootPOA = PortableServer::POA::_narrow(obj);

CORBA::PolicyList policies;
policies.length(1);
policies[(CORBA::ULong)0] = rootPOA->create_lifespan_policy(PortableServer::PERSISTENT);

//get the POA Manager
PortableServer::POAManager_var poa_manager = rootPOA->the_POAManager();

//create myPOA with the right policies
PortableServer::POA_var myPOA = rootPOA->create_POA("hello", poa_manager, policies);

//create the servant
HelloImpl helloServant;

//get the ID for the servant
PortableServer::ObjectId_var servantID = PortableServer::string_to_ObjectId("Helloo");

//activate the servant with the servant ID on the above created POA
myPOA->activate_object_with_id(servantID, &helloServant);

//activate the POA Manager
poa_manager->activate();

cout << "Waiting for requests..." << endl;

orb->run();
}
catch(const CORBA::Exception& e)
{
cerr << e << endl;
return 1;
}
return 0;
}

3.9 Makefile.cpp
include ../stdmk_nt

EXE = HelloClient.exe HelloServer.exe

all: $(EXE)

clean:
del *.obj
del *.exe
del *_c.cpp
del *_s.cpp
del *.hh
# del *.log
# del *.out
# del *.ilk
# del *.pdb

#
# "HelloApp" specific make rules
#

Hello_c.cpp: Hello.idl
$(ORBCC) Hello.idl

Hello_s.cpp: Hello.idl
$(ORBCC) Hello.idl

HelloClient.exe: Hello_c.obj HelloClient.obj
$(LINK_EXE) /out:HelloClient.exe HelloClient.obj /
Hello_c.obj $(LIBORB) $(STDCC_LIBS)

HelloServer.exe: Hello_s.obj Hello_c.obj HelloServer.obj
$(LINK_EXE) /out:HelloServer.exe HelloServer.obj /
Hello_s.obj Hello_c.obj $(LIBORB) $(STDCC_LIBS)

3.10 Build
prompt>vbmake
prompt>nmake –f Makefile.cpp

3.11 Results:
Server: vbj HelloServer(java)
Client: vbj HelloClient(java)
http://p.blog.csdn.net/images/p_blog_csdn_net/pathuang68/EntryImages/20090616/vb5.jpg
Fig. 5
MT = 1464.25 (ms)

Server: HelloServer.exe(c++)
Client: vbj HelloClient(java)
http://p.blog.csdn.net/images/p_blog_csdn_net/pathuang68/EntryImages/20090616/vb6.jpg
Fig. 6
MT = 1424.75(ms)

Server: vbj HelloServer(java)
Client: HelloClient.exe(c++)
http://p.blog.csdn.net/images/p_blog_csdn_net/pathuang68/EntryImages/20090616/vb7.jpg
Fig. 7
MT = 57.5(ms)

Server: HelloServer.exe(c++)
Client: HelloClient.exe(c++)
http://p.blog.csdn.net/images/p_blog_csdn_net/pathuang68/EntryImages/20090616/vb8.jpg
Fig. 8
MT = 55(ms)

As you can see, the efficiency is mainly due to the client side.
Client written in C++, the mean time of each call is (57.5 + 55)/2 = 56.25(ms)
Client written in Java, the mean time of each all is (1464.25 + 1424.75)/2 = 1444.5(ms)

Server written in C++, the mean time of each call is (1424.75 + 55)/2 = 739.875(ms)
Server written in Java, the mean time of each all is (1464.25 + 57.5)/2 =760.875 (ms)

3.12 Conclusion
For efficiency, C++ is better than Java
For conveniency, Java is better than C++
For compromise between efficiency and conveniency, write server side in Java, write client side in C++

Chapter 4 Using the tie Mechanism
In this chapter, we will rewrite the Hello example in Chapter 3 by using the tie mechanism.

As we all know, object implmenetation classes normally inherit from a servant class generated either by the idl2cpp or the idl2java compiler. The servant class, in turn, inherits from org.omg.PortableServer.Servant(Java) or PortableServer.Servant::Servant(C++). When it is not convenient or possible to change existing classes to inherit from the Visibroker Edition servant class, the tie mechanism offers an attractive alternative.

With using the tie mechanism, two additional files are generated from the IDL compiler
1. <InterfaceName>POATie
It defers implementation of all IDL defined methods to a delegate. The delegate implements the interface
<InterfaceName>Operations. Legacy implementations can be trivially extended to implement the operations interface and in turn delegate to the real implementation.
2. <InterfaceName>Operations
It defines all of the methods that must be implemented by the object implementation. This interface acts as the delegate object for the associated <InterfaceName>POATie class when the tie mechanism is used.

4.1 The IDL file – Hello.idl
module HelloApp
{
interface Hello
{
string sayHello1(in string name);
string sayHello2();
long add(in long op1, in long op2);
};
};
same as that of chapter 3.

4.2 Client in Java
import java.util.*; //In order to get system time
public class HelloClient
{
public static void main(String[] args)
{
long i;
Date dbegin;
dbegin = new Date();

java.util.Date dend;

//initialize the ORB
org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args, null);

//get the servantID
byte[] servantID = "Helloo".getBytes();
//---added by Patrick
com.inprise.vbroker.CORBA.BindOptions bindOptions =
new com.inprise.vbroker.CORBA.BindOptions(false, true);

//locate the servant. give the full POA name and the servant ID
//HelloApp.Hello helloServant =
// HelloApp.HelloHelper.bind(orb, "/hello", servantID); //be replaced by following line
HelloApp.Hello helloServant =
HelloApp.HelloHelper.bind(orb, "/hello", servantID, "127.0.0.1", bindOptions);

String name = args.length > 0 ? args[0] : "Patrick H. Huang";

int op1 = args.length > 1 ? Integer.parseInt(args[1]) : 0;
int op2 = args.length > 2 ? Integer.parseInt(args[2]) : 0;

System.out.println("Hello! " + helloServant.sayHello1(name) + ".");
System.out.println(helloServant.sayHello2());
System.out.println(op1 + " + " + op2 + " = " + helloServant.add(op1, op2));

dend = new Date();
i = (dend.getTime() - dbegin.getTime());
System.out.println(i + " millisecond elapsed!");
}
}
same as that of chapter 3.

Note:
This experimental environment is that the Server and Client will run on the same host, if the computer is not connected into a network such as LAN, we can use 127.0.0.1 as the IP address of the Server; on the other hand, if the computer is connected into a network, you should use the IP address of that computer, for example, my computer’s IP address is 192.168.0.198 instead, otherwise the Client will prompt an error message like:
http://p.blog.csdn.net/images/p_blog_csdn_net/pathuang68/EntryImages/20090616/vb9.jpg
Fig. 9
when you change IP address from 127.0.0.1 to 192.168.0.198 or from 192.168.0.198 to 127.0.0.1, you should restart the osagent.

4.3 Implementation of Servant in Java
//HelloImpl.java
//public class HelloImpl extends HelloApp.HelloPOA replace by the following line of code in order to use tie mechanism
public class HelloImpl implements HelloApp.HelloOperations
{
static int i = 0;

public String sayHello1(String name)
{
i++;
System.out.println("***************** Be invoked for " + i + " times. *****************");
return name;
}

public String sayHello2()
{
return "My name is Patrick, it is really very nice to meet you!";
}

public int add(int op1, int op2)
{
return op1 + op2;
}
}
as you would like to use tie mechanism, so
public class HelloImpl extends HelloApp.HelloPOA will be replaced by
public class HelloImpl implements HelloApp.HelloOperations

anything else is exactly the same as that of chapter 3.

4.4 Server in Java
//HelloServer.java
import org.omg.PortableServer.*;

public class HelloServer
{
public static void main(String[] args)
{
try
{
//initialize the ORB
org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args, null);

//get a reference to the root POA
POA rootPOA = POAHelper.narrow(orb.resolve_initial_references("RootPOA"));

//create policies for my persistent POA
org.omg.CORBA.Policy[] policies =
{
rootPOA.create_lifespan_policy(LifespanPolicyValue.PERSISTENT)
};

//create my POA
POA myPOA = rootPOA.create_POA("hello", rootPOA.the_POAManager(), policies);

/**** 1 *****
//create the servant
HelloImpl helloServant = new HelloImpl();
***** 1 ****/
//Using tie
HelloApp.HelloPOATie tie = new HelloApp.HelloPOATie(new HelloImpl());

//get the ID for the servant
byte[] helloServantID = "Helloo".getBytes();

/**** 1 *****
//activate the servant with the servant ID on the above created POA
myPOA.activate_object_with_id(helloServantID, helloServant);
***** 1 ****/
//Using tie
myPOA.activate_object_with_id(helloServantID, tie);

//activate the POA manager
rootPOA.the_POAManager().activate();
myPOA.the_POAManager().activate();
//wait for incoming requests

System.out.println("Waiting for requests...");
//orb.perform_work();
orb.run();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
as you can see, there are only 2 places(as highlighted) is changed in order to use tie mechanism.

4.5 Client in C++
#include "Hello_c.hh"
#include "corba.h" //在使用BindOptions结构时应包含 corba.h 文件
#include "time.h" // OK on Unix and Windows
#include "sys/timeb.h" // specifically for Windows

USE_STD_NS

int main(int argc, char* const* argv)
{
try
{
//time_t t1 = time(NULL); // will be OK on Unix and Windows
struct _timeb timebuffer1; // specifically for Windows
_ftime(&timebuffer1); // specifically for Windows

//initialize the ORB
CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);

//get the servant ID
PortableServer::ObjectId_var servantID = PortableServer::string_to_ObjectId("Helloo");

//locate the servant. give the full POA name and the servant ID
//HelloApp::Hello_var helloServant = HelloApp::Hello::_bind("/hello", servantID);

//the following line is added by Patrick to replace the the above line.
//advantage: will speed up to look for the osagent.
HelloApp::Hello_var helloServant =
HelloApp::Hello::_bind("/hello", servantID, "127.0.0.1", CORBA_Object::_default_bind_options(), orb);

const char* name = argc > 1 ? argv[1] : "Patrick";
long op1 = argc > 2 ? atol(argv[2]) : 0l;
long op2 = argc > 3 ? atol(argv[3]) : 0l;

cout << "Hello! " << helloServant->sayHello1(name) << "." << endl;
cout << helloServant->sayHello2() << endl;
cout << op1 << " + " << op2 << " = " << helloServant->add(op1, op2) << endl;

//time_t t2 = time(NULL);
struct _timeb timebuffer2; // specifically for Windows
_ftime(&timebuffer2); // specifically for Windows

cout << (timebuffer2.time - timebuffer1.time) * 1000 + timebuffer2.millitm - timebuffer1.millitm
<< " milliseconds elapsed." << endl;
}
catch(const CORBA::Exception& e)
{
cerr << e << endl;
return 1;
}
return 0;
}
same as that of chapter 3.

4.6 Implementation of Servant in C++
#include "Hello_s.hh"
#include "string.h"
#include <math.h>

USE_STD_NS

class HelloImpl : public virtual POA_HelloApp::Hello //, public virtual PortableServer::RefCountServantBase
{
public:
char* sayHello1(const char* name)
{
/* char* str;
str = '/0';
str = (char*)strcat((char*)"Hello! ", name);
str = str + '/0';
return str;
*/
static CORBA::Long times = 0;
times++;
cout << "******************* Be invoked for " << times << " times. *******************" << endl;
return (char*)name;
}

char* sayHello2()
{
return "My name is Patrick, it is really very nice to meet you!";
}

CORBA::Long add(CORBA::Long oper1, CORBA::Long oper2)
{
return oper1 + oper2;
}
};
same as that of chapter 3.

4.7 Server in C++

#include "HelloImpl.h"

USE_STD_NS

int main(int argc, char* const* argv)
{
try
{
//intialize the ORB
CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);

//get a reference to the root POA
CORBA::Object_var obj = orb->resolve_initial_references("RootPOA");
PortableServer::POA_var rootPOA = PortableServer::POA::_narrow(obj);

CORBA::PolicyList policies;
policies.length(1);
policies[(CORBA::ULong)0] = rootPOA->create_lifespan_policy(PortableServer::PERSISTENT);

//get the POA Manager
PortableServer::POAManager_var poa_manager = rootPOA->the_POAManager();

//create myPOA with the right policies
PortableServer::POA_var myPOA = rootPOA->create_POA("hello", poa_manager, policies);

//**** 1 ****
//create the servant
HelloImpl helloServant;
//***** 1 ****/
//Using tie
POA_HelloApp_Hello_tie<HelloImpl> tieServer(helloServant);

//get the ID for the servant
PortableServer::ObjectId_var servantID = PortableServer::string_to_ObjectId("Helloo");

/**** 1 ****
//activate the servant with the servant ID on the above created POA
myPOA->activate_object_with_id(servantID, &helloServant);
***** 1 ****/
//Using tie
myPOA->activate_object_with_id(servantID, &tieServer);

//activate the POA Manager
poa_manager->activate();

cout << "Waiting for requests..." << endl;

orb->run();
}
catch(const CORBA::Exception& e)
{
cerr << e << endl;
return 1;
}
return 0;
}

Note:
According to the definition in Hello_s.cpp as:
template <class T> class POA_HelloApp_Hello_tie : public ::POA_HelloApp::Hello
{

POA_HelloApp_Hello_tie (T& t): _ptr(&t), _poa(NULL), _rel((::CORBA::Boolean)0) {}
….
}
so, POA_HelloApp_Hello_tie<HelloImpl> tieServer(helloServant); in the HelloServer.C can be written as
POA_HelloApp_Hello_tie<HelloImpl> tieServer(&helloServant); And it works perfect as well.

4.8 Results and Conclusion
Almost the same as that of chapter 3.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: