[转帖]Tuxedo缓冲区的封装代码,成就你打造通用的tuxedo客户端_MQ, Tuxedo及OLTP讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  MQ, Tuxedo及OLTP讨论区 »
总帖数
1
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 4137 | 回复: 0   主题: [转帖]Tuxedo缓冲区的封装代码,成就你打造通用的tuxedo客户端        下一篇 
haili.yang
注册用户
等级:少校
经验:936
发帖:71
精华:1
注册:2012-12-24
状态:离线
发送短消息息给haili.yang 加好友    发送短消息息给haili.yang 发消息
发表于: IP:您无权察看 2012-12-25 11:12:06 | [全部帖] [楼主帖] 楼主

Tuxedo缓冲区的封装代码,成就你打造通用的tuxedo客户端(一)



我们知道tuxedo有4种类型的缓冲区,下面我将演示如何封装这4种类型的缓冲区

并封装好了之后,发送给tuxedo,然后获得返回数据,并进行解析,输出 整个过程,完整的封装了tuxedo。并且封装成为一个通用的tuxedo客户端。

一:,我们来分析一下输入的配置文件格式如下:

servicename@wsnaddr@typebuffer[/email]@数据成员名称:inout@数据成员类型@数据成员名称:inout@类型..(目前支持int,double,float,char,long)


对于fml类型的缓冲区需要提供FLDTBLDIR32=路径和FIELDTBLS32=值, 例如:

string类型:[url=]SWAP@//192.168.9.33:21550@string@send:in:char[1024]@recv:out:char[10[/url] 24]表示SWAP服务在那个主机上,服务端接收缓冲区类型为STRING,入参数据成员名称:send,ch

ar[1024]长度,出参数据成员的名称:recv,char[1034]

view32类型:INSERTVIEW@//192.168.9.33:21552@view32@rid:inout:int@rname:inout:lon [email=g@rsal:inout:char[8]g@rsal:inout:char[8[/email]]

表示INSERTVIEW这个服务在主机上,服务端接收VIEW32缓冲区,入参的数据成员名称分别是 :rid,rname,rsal  数据成员的类型分别是:int类型,long,和char类型,也就是struct有3个成员

fml32类型:[url=]INSERTFML@//192.168.9.33:21552@fml32:FLDTBLDIR32=/home/guowl/fml:FIELDTBLS32=regions@id:inout:long@name:inout:char[8]@sal:inout:char[8[/url]]

表示INSERTFML这个服务在主机上,服务端接收FML32缓冲区,域表头文件的目录在/home/guowl/fml,域表头文件名称regions 数据成员名称分别是:id,name,sal,类型分别是:long,char[8],char[8] 然后将这个服务定义文件,读入到一个char

*的指针里面,

char * GetServiceDef()//获取服务配置文件
{
      char sTmp[255]="";
      static char sBuffer[8192]="";
      strcpy(sTmp,"/home/guowl/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;
}


二.我们来介绍一下对外的统一接口函数:

//4个入参,服务名,请求的入参数据,状态,���data,这个data指针是/home/guowl/servi ce.def里面的内容//g_OutputData,g_InputData,g_sname,tuxlog均为全局的char一维数组
char * InterFace( char *ServiceName, char *InputData,int *ServiceStatus, char *data )
{
memset(g_OutputData,0,BUFFLEN*sizeof(char));//全局一维数据初始化 memset(g_InputData,0,BUFFLEN*sizeof(char));
//由于入参是指针,极其容易发生变化,所以先把请求的入参数据和请求的服务名称复制到


  g_InputData和g_sname

memcpy(g_InputData,InputData,strlen(InputData)); g_InputData[strlen(g_InputData)]=0;
memset(g_sname,0,sizeof(g_sname));//先初始化,再复制,因为是全局变量
memcpy(g_sname,ServiceName,strlen(ServiceName));
sname[strlen(sname)]=0;
memset(tuxlog,0,sizeof(tuxlog));//日志数组的初始化,tuxlog表示日志的一维数组
if(strlen(g_InputData)==0) {//判断请求的入参数据是否为空
      *ServiceStatus=-3;
      return (char*)NULL;
} //gx是一个全局的对象,他是TuxPost类型的一个对象,后面会介绍每个类的声明以及类的?  饔?
gtux.m.clear();
memset(gtux.Buffer,0,sizeof(gtux.Buffer));
//*ServiceStatus= 1;//表示请求状态,默认为-1,表示失败
//g_out1也是全局的二维char数组,用来分割使用,配合splitStr函数使用。
//splitStr函数返回指针data里面,使用"\n"为分隔符,能把data分割 每一份,从前往后,可以用g_out1[1],g_out1[2]....
//下面讲公用函数的时候,会介绍的
memset(g_out1,0,sizeof(g_out1));
intiNum=splitStr(data,"\n",g_out1);
//Stype是TuxPost类型里面表示类型,也就是缓冲区类型,STRING/VIEW32/FML32,注意全 部都是大写,他也需要初始化
memset(gtux.Stype,0,sizeof(gtux.Stype));
//RedoSvc是TuxPost类型里面的一个成员函数,会查询本次请求以前有没有请求过同样的 服务
//如���请求过,则会优化一些细节,减少系统的消耗,也就是一个容器而已
gtux.RedoSvc(g_sname);
string RedoServiceName;
string Redoinput;
RedoServiceName.assign(sname); //获取redo servicename..。
Redoinput.assign(g_InputData);
//获取本次请求的redo  请求入参
if(Redoflag!=1) {//Redoflag也是全局变量,=1表示以前请求过,!=1表示以前没请求过
      for(int i=0;i<iNum;++i) {
            if(strcmp(g_out1[i],"")!=0) {
                  memset(sout,0,sizeof(sout));
                  memcpy(sout,g_out1[i],sizeof(g_out1[i]));
                  sout[strlen(g_out1[i])]=0;
                  //上面的for循环是针对配置文件service.def的每一行数据,也就是g_out[i],判断是否 为空。。
                  if(gtux.VeiwInit(sout,g_sname)==0) {
                        break;
                        //针对每一行的数据做一些初始化和成员的识别,包括gtux.Stype和gtux.wsnaddr等等
                  }
            }
      }
}
if(strcmp(gtux.Stype,"")==0) {//判断是否识别到了本次请求的缓冲区的类型信息 *ServiceStatus=-2;
      memcpy(tuxlog,gtux.m.c_str(),gtux.m.size());
      //如果没有识别到。。。那么输出日志 的错误信息,并且返回
      return (char*)NULL;
}
if(strncmp(gtux.Stype,"FML",3)==0) {//如果是FML类型,
      if(gtux.FmlDest()==-1) { //分配接收缓冲区,发送缓冲区以及初始化连接tuxedo等等。
            *ServiceStatus=gtux.m_status;
            memcpy(tuxlog,gtux.m.c_str(),gtux.m.size());//如果上述操作失败了,返回日志错误 信息
            return NULL;
      }
      if(gtux.CallAnaly(g_InputData,sname)==-1) {//分析本次的请求入参数据,根据入参数据,进行缓冲区的数据填充也就是缓冲?鳩ML成员的数据填充
            *ServiceStatus=gtux.m_status;
            memcpy(tuxlog,gtux.m.c_str(),gtux.m.size());//填充失败..
            return NULL;
      }
      if(gtux.FInvoke(sname)==-1) {//呼叫TUXEDO的服务..。
            *ServiceStatus=gtux.m_status;
            memcpy(tuxlog,gtux.m.c_str(),gtux.m.size());
            return NULL;//失败了。。
      }
      gtux.DelMem();//做一些清理工作。。。
}
if(strncmp(gtux.Stype,"VIEW",4)==0) {//VIEW32缓冲区
      if(gtux.ViewDest()==-1) {//分配VIEW32缓冲区,初始化连接tuxedo等等
            *ServiceStatus=gtux.m_status; memcpy(tuxlog,gtux.m.c_str(),gtux.m.size()); return NULL;
      }
      if(gtux.CallAnaly(g_InputData,sname)==-1) {//分析本次请求的入参数据,之后进行发送缓冲区数据的填充
            *ServiceStatus=gtux.m_status; memcpy(tuxlog,gtux.m.c_str(),gtux.m.size()); return NULL;
      }
      if(gtux.VInvoke(sname)==-1) {//呼叫view32的tuxedo服务
            *ServiceStatus=gtux.m_status;
            memcpy(tuxlog,gtux.m.c_str(),gtux.m.size()); return NULL;
      }
      gtux.DelMem();//做清理工作
}
if(strncmp(gtux.Stype,"STRING",6)==0 ) {//STRING缓冲区的处理方式.
      if(gtux.StringDest()==-1) {
            *ServiceStatus=gtux.m_status; memcpy(tuxlog,gtux.m.c_str(),gtux.m.size()); return NULL;
      }
      if(gtux.CallAnaly(g_InputData,sname)==-1) {
            *ServiceStatus=gtux.m_status; memcpy(tuxlog,gtux.m.c_str(),gtux.m.size());
            return NULL;
      }
      if(gtux.SInvoke(sname)==-1) {
            *ServiceStatus=gtux.m_status; memcpy(tuxlog,gtux.m.c_str(),gtux.m.size());
            return NULL;
      }
      gtux.DelMem();
}
//上面每种缓冲区的处理流程完成了之后,就开始把gtux.Buffer里面的数据,返回?  鋈?,环游中间产生的日志信息等等.
if(strcmp(gtux.Buffer,"")!=0) {
      memset(g_OutputData,0,BUFFLEN*sizeof(char));
      memcpy(g_OutputData,gtux.Buffer,strlen(gtux.Buffer));
}
memcpy(tuxlog,gtux.m.c_str(),gtux.m.size());
*ServiceStatus=gtux.m_status; return g_OutputData;
}


  三.介绍公用的成员函数,以及涉及到的类和函数的声明:

#define  IN 0 //入参标志
#define  OUT 1  //出参标志
#define  INOUT 2 //即是出参,又是入参标志
#define  BUFFLEN  20480
extern  char g_out1[255][255];
extern  char  g_out2[255][255];
extern  char  g_FLDTBLDIR32[255];
extern  char g_FIELDTBLS32[255];
extern char  g_WSNADDR[255];
extern char  sname[255];
extern char  sout[255];
extern  char  g_OutputData[BUFFLEN];
extern  char g_InputData[BUFFLEN];
extern int Redoflag;


extern TPINIT* tpinitbuf; 上面都是全局变量的声明.

class TuxPost
{
private:
char m_CurWSNADDR[64];
bool m_bInConnection; //是否正处在连接之中
char FIELDTBLS32[255];//类里面的FML域表头文件目录
char FLDTBLDIR32[255];
char *v_RecBuff; //view32接收缓冲区
char * v_SendBuff; //view32发送缓冲区
char * f_RecBuff; //fml32接收缓冲区\
char * f_SendBuff;//fml32发送缓冲区
char * s_RecBuff;//string接收缓冲区
char * s_SendBuff; //string发送缓冲区 Veiw gview;//辅助类对象。。。
public:
char Buffer[BUFFLEN];//统一的,用于接收tuxedo返回的处理��果
char Stype[255];//缓冲区类型
bool TuxInit();
bool TuxTerm();
int StringSrc();//分配发送缓冲区
int StringDest(); //分配接收缓冲区函数
int VeiwInit(char*a,char
*sname);//初始化service.def里面的内容,查找到和本次请求入参一样的tuxedo服务记录?⑶易龀稍钡某跏蓟?
int SetVeiwBuffer();//填充VIEW32发送缓冲区
int CallAnaly(char *p,char *sname);//分析本次请求的入参数据,以方便每个缓冲区的填充
int ViewDest();
int ViewSrc();
int BufferViewSend();//填充VIEW32的发送缓冲区
int BufferFmlSend(char *data,char *value,const char *p);//填充fml缓冲区,来源数据是
view gv
int SetSendFml(char *data,char *value,int iNum);
int BufferStringSend();//填充STRING发送缓冲区
int BufferStringRec();
int BufferFmlRec();
int FmlDest();
int FmlSrc();
void DelMem();//清理现场的函
int VInvoke(char *sname);//view32的tpcall版本
int BufferViewRec();
//处理VINVOKE后,组织数据返回结果
int OutViewBuffer();//处理返回结果
int FInvoke(char *sname); //FML版本的tpcall
int SInvoke(char *sname);
//STRING版本的tpcall
int SetServType();
//设置本次请求的缓冲区类型
int Param(const char*); //判断是入参,出参的函数
map<string,Trie> themap; //这个MAP用于保留每次请求后的结果。。以方便下次请求的成员设置
int RedoCallAnaly(string,string);//分析本次请求是否已经请求过
int makeTrie(); //产生一个Trie的对象,用于存储themap
int RedoSvc(string s); //判断是否请求过
string RedoStr;
map<string,VeiwType>RedotheView; //如果请求过,这个容器是自动保存业务成员信息的容器
int CheckFmlTables();//加入了检查FML请求成员的合法性.




赞(0)    操作        顶端 
总帖数
1
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论