我们知道tuxedo有4种类型的缓冲区,下面我将演示如何封装这4种类型的缓冲区
并封装好了之后,发送给tuxedo,然后获得返回数据,并进行解析,输出
整个过程,完整的封装了tuxedo。并且封装成一个小系统。
第一:,我们来分析一下我们这个小系统的输入:
1.servicename,调用的tuxedo服务的名称。
2.sindata 系统的入参数据,也就是传递给tuxedo的数据,需要经过分析和转化才能传递给tuxedo
3.soutdata 系统的出参数据,也就是tuxedo返回给我们系统的数据。
4.stype 本次处理的状态,默认为-1,如果处理成功,那么这个状态会变成0
5.servicedef tuxedo服务端的服务定义文件,不同缓冲区类型的服务定义文件是不一样的
例如:
格式如下:
servicename@wsnaddr@typebuffer@业务成员名称:输入/输出@业务成员类型(目前支持int,double,float,char,long)
对于fml类型的缓冲区需要提供FLDTBLDIR32=和FIELDTBLS32=
string类型: SWAP@192.168.136.129:7200@string@send:in@char[500]
view32类型:INSERT@//192.168.136.129:7200@view32@rid:in@int@rname:in@int@rsal:in@char[8]
fml32类型:INSER1T@//192.168.136.129:7201@fml32:FLDTBLDIR32=/home/billapp2/simpapp/fml:FIELDTBLS32=regions@rid:in@int@rname:in@int@rsal:in@char[8]
然后将这个服务定义文件,读入到一个char *的指针里面,
char * SetServDef()//获取服务配置文件
{
char sTmp[255]="";
static char sBuffer[8192]="";
strcpy(sTmp,"/home/billapp2/service.def");//服务配置文件的路径
FILE *fp;
fp=fopen(sTmp,"r");
if(fp==NULL) {
printf(" cannot open 配置文件 file %s\n",tmp);
//return -1;
}
memset( sBuffer,0,sizeof(sBuffer));//读取到sBuffer
fread(sBuffer,255,100,fp);
return sBuffer;//返回sBuffer;
}
然后是调用:
char *b=SetServDef();
soutdata=c_face(servicename,sindata,&stype,b);//此处的c_face函数就是接口函数;
基本上就是这么调用的。。。
下面我们来看一下统一对外的接口:
char * c_face( char *sname, char *sin,int *status, char *data ) {
static view32 gv1;
static tux sb;
static SBLOG log;
char sout[255][255];
char ssout[255]="";
char sname[40]="";
static char sout[2000]="";
*status=-1;
sv.xplitstr(data,"n",out);
for(int i=0;i<255;++i) {
if(strcmp(sout,"")!=0) {
memset(sout,0,sizeof(sout));
memcpy(sout,sout,sizeof(sout));
if(sb.view32Init(sout,sname)==0)
break;
}
}
if(strncmp(sb.Stype,"FML",3)==0) {
sb.analysin(chrServiceInputPara,sname);
sb.fmlcall(sname);
sb.deletememory();//FML缓冲区的调用方法
}
if(strncmp(sb.Stype,"VIEW",4)==0) {
sb.analysin(chrServiceInputPara,sname);
sb.viewcall(sname);
sb.deletememory();//VIEW缓冲区的调用方法
}
if(strncmp(sb.Stype,"STRING",6)==0) {
sb.analysin(chrServiceInputPara,sname);
sb.stringcall(sname);
sb.deletememory();//string缓冲区的调用方法
}
memset(chrServiceOutputPara,0,sizeof(chrServiceOutputPara));
if(strcmp(sb.Buffer,"")!=0)
{
strcpy(chrServiceOutputPara,sb.Buffer);
*status=0;
}
return chrServiceOutputPara;
}
第二:
第二点,下来我们分析一下建立对应关系,也就是我们的小系统和用户的业务数据成员之间建立映射关系:
建立映射关系,我打算使用map来做,map的名称:themapview32map
1.我们来看一下声明:
struct view32Type //这个类的作用是建立业务数据成员,业务成员长度以及业务数据成员的类型
{
string name;//业务成员名称
string value;//业务成员的长度
string tmp;//业务成员的类型
view32Type(string a,string b,string c);//构造函数,构造这么一个对象比如:empno 4 int,其中empno是业务名称,4是大小,int是类型
view32Type();
~view32Type();
int ifadd(char *,char *);
friend string IntToString(int);//声明int怎么到string类型的转化
};
string DoubleToString(LDOUBLE n);//声明了double到string类型的转化
string FloatToString(LFLOAT n);//生命了float到string类型的转化
string IntToString(int);//声明int怎么到string类型的转化
string AddSpace(string,int);//这个函数是在将一个string,填充到固定的大小。string a="123"。比如AddSpace(a,5)则返回"123"
string CharToString(char *n);//这个函数是将char*转化为string
char *delspace(char *str);//这个函数是删除字符串str的前后空格
struct view32//这个类,是定义了50个string成员的一个类,用来和用户的业务成员建立一一对应的关系
{
string sb1;
string sb2;
string sb3;
//剩下的47个元素。大家自己想吧
view32();
~view32();
int dealrecord(char *,char *);//此函数比较重要,用户处理每一行的的服务定义文件的数据
bool Printview32();//打印map里面的数据
int xplitstr(char *ps,char *split,char dest[][255]);//此函数也很重要,用于分析一行数据里面,用固定字符分割,然后可以获取分隔字符的前后类容
map<string,view32Type> themapview32;//map的声明
bool mapviewup();//此函数比较重要,用于在view类型缓冲区中做结构体内存成员对齐和结构体本身的内存对齐
SBLOG m;
int GetData(char *data,char *value); //此函数重要,用于将业务的数据,赋值给我们定义的结构体成员,比如:GetData(empno,123),由于empno在themapview32这个map里面对应的是v1,所以赋值之后,就变成了v1=123;
int Sumview32();//获取themapview32这个map里面的所有的成员的大小的总和
friend string IntToString(int);
friend string AddSpace(string,int);
char wsnaddr[255];//这个是wsnaddr,从服务定义文件获取
char ServType[255];//本次服务所接收的类型,从服务定义文件获取
};
#endif
2.
下面呢,我们开始建立v1~v50和业务数据成员的对应关系。
//处理每���数据
比如:
INSERT@//192.168.136.129:7200@view32@rid:in@int@rname:in@int@rsal:in@char[8]
int view32::dealrecord(char *sRecord,char *sname) {//输入是服务定义文件里面的每一行内容,记住是每一行
char sout[255][255];//定义二维数组
char sTmp[255]="";
int iNum=0;
memset(sout,0,sizeof(out));
iNum = xplitstr(sRecord,"@",out); //isalt.def里面的每个记录是用@来分割的
if (iNum<=2) {
m<<"@符号太少,服务配置错误,请检查";
return -1;
}//经过xplitstr函数处理之后,那么sout[0]="INSERT",sout[1]="192.168.136.129:7200",sout[2]=view32,sout[3]=rid:in
//sout[4]=int,sout[5]=rname:in,sout[6]=int sout[7]=char[8]
memset(sTmp,0,sizeof(sTmp));
strcpy(sTmp,sout[0]); //获取每行的第一列,是service_name
sTmp[sizeof(sTmp)]=0;
AllTrim(sTmp);
int i=3;
char sout2[255][255];
if(strncmp(sTmp,sname,sizeof(sname))==0) { //判断本行的servicename是否为请求的sname,如果是,继续
strcpy(wsnaddr,sout[1]);//将o赋值给sout[1]即本tuxedo服务对应的wsnaddr
wsnaddr[sizeof(sout[1])]='0';
strcpy(ServType,sout[2]);
ServType[strlen(ServType)]='0';
if(strcmp(sout,"")!=0 && strcmp(sout[i+1],"")!=0) {//判断sout[3],sout[4]是否为空
memset(out2,0,sizeof(out2));
if(xplitstr(sout,":",out2)==2) {//做第二次分割,也就是对out3[]=rid:in,用":"字符再分割一次,分割输出到out2[0]=rid,和out2[1]=in //重要注释
view32Type a(out2[0],sout[i+1],sout[i+1]); //读取业务数据成员名称,和业务数据成员类型,分别填充到map里面, //重要注释
//将out2[0]="rid",sout[i+1=4]=int,sout[i+1=4]="int"用view32Type的构造函数进行构造a,构造后a的值:rid 4int //重要注释
//先绑定到a里面,然后和v1~v50分别绑定到map里面 //重要注释
themapview32.insert(map<string,view32Type>::value_type("v1",a));//插入map。。。这里插入后的map就是 v1rid4int //重要注释
} //重要注释
} //重要注释
if(strcmp(sout[i+1],"")==0 && strcmp(sout,"")!=0) {//判断如果sout[3]!=""但是sout[4]==""这种情况,是因为没有假如数据成员的类型,应给出提示 //重要注释
m<<"业务数据成员类型错误,请改正;";
return -1;
}
i+=2;//后面是依次循环。。。总共循环了50次,每次I+=2。。。呵呵。。
if(strcmp(sout,"")!=0 && strcmp(sout[i+1],"")!=0) {
memset(out2,0,sizeof(out2));
if(xplitstr(sout,":",out2)==2) {
view32Type a(out2[0],sout[i+1],sout[i+1]); //读取业务数据成员名称,和业务数据成员类型,分别填充到map里面,
//先绑定到a里面,然后和v1~v50分别绑定到map里面
themapview32.insert(map<string,view32Type>::value_type("v2",a));
}
}
if(strcmp(sout[i+1],"")==0 && strcmp(sout,"")!=0) {
m<<"业务数据成员类型错误,请改正;";
return -1;
}
i+=2;
if(strcmp(sout,"")!=0 && strcmp(sout[i+1],"")!=0) {
memset(out2,0,sizeof(out2));
if(xplitstr(sout,":",out2)==2) {
view32Type a(out2[0],sout[i+1],sout[i+1]); //读取业务数据成员名称,和业务数据成员类型,分别填充到map里面,
//先绑定到a里面,然后和v1~v50分别绑定到map里面
themapview32.insert(map<string,view32Type>::value_type("v3",a));
}
}
if(strcmp(sout[i+1],"")==0 && strcmp(sout,"")!=0) {
m<<"业务数据成员类型错误,请改正;";
return -1;
}
//剩下的代码,各位自己想吧,本文只填充3个
return 0;
}
}
上面的函数建立了v1~v50和tuxedo service的一一对应关系。。。这个对应关系是很重要的。。
后面的代码都是围绕着这个对应关系展开的。上面的函数用到了xplitstr这个函数。。这个函数
还是很有用的。。把它的代码贴出来。。有助于大家学习
该贴被鲲鹏展翅编辑于2012-11-20 14:19:10