本例子的目标是运行一个客户接受键入(typed input),服务器把此键入在标准输出上输出。
echo 的功能用下面的非常短的 IDL 表示。
Example 5-1.
// MyFirstOrbit program - The Echo object
// 我的第一个Orbit程序 - Echo 对象
//
// All this does is pass a string from the client to the server.
// 它所做的一切只是从客户向服务器传递一个字符串
//
interface Echo {
void echoString(in string input);
};
接口(interface)定义是定义的关键部分。每个接口定义一个对象及其方法。在这个例子的情况下只有一个方法,它接受一个字符串参数并且不返回任何东西。参数前面的 in 声明指出此参数只被传入方法。对于第一种情况,通常所有参数都是 in 参数。
这个 idl 可在 echo.idl 文件中找到,编译 idl 要经过下列步骤:$ orbit-idl echo.idl
Example 5-2.
/*
* MyFirstOrbit program. Client. Hacked by Ewan Birney
* birney@sanger.ac.uk from echo test suite.
*
*/
#include "stdio.h"
#include "orb/orbit.h"
/*
* This header file was generated from the idl
* 这是从 idl 生成的头文件
*/
#include "echo.h"
/*
* This is our Echo Object
* 这是我们的 Echo 对象
*/
Echo echo_client;
int
main (int argc, char *argv[])
{
CORBA_Environment ev;
CORBA_ORB orb;
FILE * ifp;
char * ior;
char filebuffer[1024];
/*
* Standard initalisation of the orb. Notice that
* ORB_init 'eats' stuff off the command line
* orb 的标准的初始化。注意 ORB_init 会“吃掉”部分命令行参数
*/
CORBA_exception_init(&ev);
orb = CORBA_ORB_init(&argc, argv, "orbit-local-orb", &ev);
/*
* Get the IOR (object reference). It should be written out
* by the echo-server into the file echo.ior. So - if you
* are running the server in the same place as the client,
* this should be fine!
* 得到 IOR (对象引用)。它被 echo-服务器写到文件 echo.ior。
* 所以如果服务器与客户在同一地方运行,这将是良好的。
*/
ifp = fopen("echo.ior","r");
if( ifp == NULL ) {
g_error("No echo.ior file!");
exit(-1);
}
fgets(filebuffer,1024,ifp);
ior = g_strdup(filebuffer);
fclose(ifp);
/*
* Actually get the object. So easy!
* 真正得到对象。太容易了!
*/
echo_client = CORBA_ORB_string_to_object(orb, ior, &ev);
if (!echo_client) {
printf("Cannot bind to %s\n", ior);
return 1;
}
/*
* Ok. Now we use the echo object...
* OK. 现在使用 echo 对象...
*/
printf("Type messages to the server\n. as the only thing on the line stops\n");
while( fgets(filebuffer,1024,stdin) ) {
if( filebuffer[0] == '.' && filebuffer[1] == '\n' )
break;
/*
* chop the newline off
* 切掉换行符
*/
filebuffer[strlen(filebuffer)-1] = '\0';
/*
* using the echoString method in the Echo object
* this is defined in the echo.h header, compiled from echo.idl
* 在 Echo 对象中使用 echoString 方法
* 这个方法在由 echo.idl 文件编译出的 echo.h 头文件中定义。
*/
Echo_echoString(echo_client,filebuffer,&ev);
/*
* catch any exceptions (eg, network is down)
* 捕获任何例外(例如网络被关闭)
*/
if(ev._major != CORBA_NO_EXCEPTION) {
printf("we got exception %d from echoString!\n", ev._major);
return 1;
}
}
/*
* Clean up
* 清除
*/
CORBA_Object_release(echo_client, &ev);
CORBA_Object_release((CORBA_Object)orb, &ev);
return 0;
}客户程序可被分成三个独立的片段。
客户程序的关键部分是调用服务器上的 echoString 方法。idl 定义
void echoString(in string input);最终变成在由 idl 生成的 echo.h 头文件中的下述定义
extern void Echo_echoString(Echo _obj, CORBA_char * astring, CORBA_Environment *ev);
下面是基于 C 编程的对象的被接受了的规则:
当然,在你的代码中不是必须依从这些规则,但 CORBA C 映射就是这样工作的,这是个不坏的解决方案。
译注:规则(1)(2)有类似的 C++ 规则(this 指针,换名规则),规则(3)的目的是线程安全。
这个服务器基本上要比客户复杂一些,但还是与客户有些通用之处。服务器必须最终进入一个监听的主循环。在此之前它必须建立 orb 并把自身的对象实现绑定(bind 也译为联编)到 orb 上。
在实际的服务器中,这变得更加复杂,但在本例子中,一旦你通过了 orb 初始化进程,一切就简单了。
/*
* MyFirstOrbit program - server. Hacked
* from Echo test suite by birney@sanger.ac.uk
*/
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "signal.h"
#include "orb/orbit.h"
#include "echo.h"
/*
* This is so we can get out a valid IOR later...
* 这使我们以后可得到一个有效的 IOR
*/
Echo echo_client = CORBA_OBJECT_NIL;
/*
* declaration of the meat of the process
*/
static void
do_echoString(PortableServer_Servant servant,
CORBA_char *astring,
CORBA_Environment *ev);
/*
* I have **no** idea what this bit does
* 我不知道这位的是干什么的
*/
PortableServer_ServantBase__epv base_epv = {
NULL,
NULL,
NULL
};
POA_Echo__epv echo_epv = { NULL, do_echoString };
POA_Echo__vepv poa_echo_vepv = { &base_epv, &echo_epv };
POA_Echo poa_echo_servant = { NULL, &poa_echo_vepv };
int
main (int argc, char *argv[])
{
PortableServer_ObjectId objid = {0, sizeof("myEchoString"), "myEchoString"};
PortableServer_POA poa;
CORBA_Environment ev;
char *retval;
CORBA_ORB orb;
FILE * ofp;
signal(SIGINT, exit);
signal(SIGTERM, exit);
CORBA_exception_init(&ev);
orb = CORBA_ORB_init(&argc, argv, "orbit-local-orb", &ev);
POA_Echo__init(&poa_echo_servant, &ev);
poa = (PortableServer_POA)CORBA_ORB_resolve_initial_references(orb, "RootPOA", &ev);
PortableServer_POAManager_activate(PortableServer_POA__get_the_POAManager(poa, &ev), &ev);
PortableServer_POA_activate_object_with_id(poa,
&objid, &poa_echo_servant, &ev);
echo_client = PortableServer_POA_servant_to_reference(poa,
&poa_echo_servant,
&ev);
if (!echo_client) {
printf("Cannot get objref\n");
return 1;
}
retval = CORBA_ORB_object_to_string(orb, echo_client, &ev);
ofp = fopen("echo.ior","w");
fprintf(ofp,"%s", retval);
fclose(ofp);
CORBA_free(retval);
fprintf(stdout,"Written the file echo.ior with the IOR of this server.\n Now waiting for requests...\n");
fflush(stdout);
CORBA_ORB_run(orb, &ev);
return 0;
}
static void
do_echoString(PortableServer_Servant servant,
CORBA_char *astring,
CORBA_Environment *ev)
{
g_message("[server] %s", astring);
return;
}
请理解这个服务器的人在此放上更多材料