第八章TUXEDO的通讯方式.docx
《第八章TUXEDO的通讯方式.docx》由会员分享,可在线阅读,更多相关《第八章TUXEDO的通讯方式.docx(45页珍藏版)》请在冰豆网上搜索。
第八章TUXEDO的通讯方式
第八章:
TUXEDO的通讯方式
TUXEDO中的客户端与服务端之间可以采用的通讯方式有:
1.同步调用方式
2.异步调用方式
3.管道方式
4.会话方式
5.消息方式
6.事件发布订阅方式
7./Q方式
注意:
1.服务端的SERVICE之间,可以采用管道方式,客户端与服务端之间不能采用。
2.客户端与服务端之间可以采用消息方式,服务端的SERVICE之间不能采用消息方式。
3.其他通讯方式在服务端的SERVICE之间,及客户端与服务端之间都可以采用。
管道方式(tpforward())在服务端编程中有说明,/Q方式在第十章中在介绍,对这两种方式在本章种不做介绍.
8.1同步调用方式
如下图所示:
在同步请求/回答方式中,客户端使用tpcall()给本地或远程的服务器(由TUXEDO系统根据公告板信息确定)发送服务请求,此时客户将传送请求服务的名字、用于请求服务的输入参数和输出参数,tpcall()发出后,客户的数据被传送至服务器,得到相应的服务处理。
在此方式下,服务器处理请求时,客户端将等待,不继续运行,直到服务器返回相应结果。
调用过程如图:
例子:
客户端通过对一个文件分块,每调用一次TPCALL()发送一块数据,把一个文件从客户端传送到服务端。
客户端与服务端采用FML32缓冲区进行通行。
在异步调用方式和会话方式中也用到该例子。
可以做一个比较。
在该例子中我们把块的大小定义为
1024字节。
采用FML32缓冲区。
FML32定义文件Myfml.h的内容:
*base100
#namenumbertypeflagscomments
FNAME1string--
BNUM3long
BID4long--
FDATA5carray--
BSIZE6long--
服务端程序Call.c的内容:
#include
#include
#include
#include
#include"fml32.h"
#include"myfml.h"
CALL(TPSVCINFO*rqst)
{
FILE*fp;
longi=0;
FBFR32*rcvbuf;
charfname[100]="";
FLDLEN32len=0;
longbid=0;
longbsize=1024;/*传送的块大小为1024字节*/
char*fdata;
rcvbuf=(FBFR32*)rqst->data;
len=sizeof(bid);
if(Fget32(rcvbuf,BID,0,(char*)&bid,&len)==-1)
{
userlog("Fget32(BID)failure:
%s",(char*)Fstrerror32(Ferror32));
tpreturn(TPFAIL,0,0,0,0);
}
len=sizeof(fname);
if(Fget32(rcvbuf,FNAME,0,fname,&len)==-1)
{
userlog("Fget32(FNAME)failure:
%s",(char*)Fstrerror32(Ferror32));
tpreturn(TPFAIL,0,0,0,0);
}
strcat(fname,".s");
if((fp=fopen(fname,"rb"))==NULL)
{
fp=fopen(fname,"wb");
}
elseif(bid==0)
{
fclose(fp);
fp=fopen(fname,"wb");
}
else
{
fclose(fp);
fp=fopen(fname,"r+b");
}
if(fp==NULL)
{
userlog("fopen()%sfailure\n",fname);
tpreturn(TPFAIL,0,0,0,0);
}
fdata=(char*)malloc(bsize+1);
if(fdata==NULL)
{
userlog("malloc(fdata)failure");
tpreturn(TPFAIL,0,0,0,0);
}
len=bsize;
if(Fget32(rcvbuf,FDATA,0,fdata,(FLDLEN32*)&len)==-1)
{
userlog("Fget32(FDATA)failure:
%s",(char*)Fstrerror32(Ferror32));
tpreturn(TPFAIL,0,0,0,0);
}
i=bid*bsize;
if(fseek(fp,i,0)!
=0)
{
userlog("fseek()failure\n");
tpreturn(TPFAIL,0,0,0,0);
}
i=fwrite(fdata,1,len,fp);
if(i!
=len)
{
userlog("fwrite()fail\n");
tpreturn(TPFAIL,0,0,0,0);
}
fclose(fp);
tpreturn(TPSUCCESS,0,NULL,0L,0);
}
客户端程序callcli.c的内容:
#include
#include
#include"atmi.h"
#include"fml32.h"
#include"myfml.h"
FBFR32*sendbuf=NULL;
char*filebuf;
FILE*fp;
log(constchar*fmt,...)
{
va_listap;
va_start(ap,fmt);
vfprintf(stdout,fmt,ap);
fflush(stdout);
va_end(ap);
fclose(fp);
tpfree((char*)sendbuf);
free(filebuf);
tpterm();
exit
(1);
}
main(intargc,char*argv[])
{
longrcvlen=0;
longfilelen=0;
longi=0;
intret=0;
longreallen=0;
longbnum=0;
longbsize=1024;/*传送的块大小为1024字节*/
FLDLEN32len=0;
if(argc!
=2)
{
(void)fprintf(stderr,"Usage:
%sfilename\n",argv[0]);
exit
(1);
}
fp=fopen(argv[1],"rb");
if(fp==NULL)
{
printf("openfile:
%sfailure\n",argv[1]);
exit
(1);
}
if(fseek(fp,0,SEEK_END)!
=0)
{
perror("fseek()failure:
");
exit
(1);
}
filelen=ftell(fp);
if(filelen==-1)
{
perror("ftell()failure:
");
exit
(1);
}
rewind(fp);
if((sendbuf=(FBFR32*)tpalloc("FML32",NULL,bsize+1024))==(FBFR32*)NULL)
{
printf("Errorallocatingsendbuffer\n");
exit
(1);
}
len=Fsizeof32(sendbuf);
if(Finit32(sendbuf,(FLDLEN32)len)==-1)
{
printf("finit32()failure\n");
exit
(1);
}
if(tpinit(NULL)==-1)
{
printf("tpinit()failure");
exit
(1);
}
filebuf=(char*)malloc(bsize);
if(filebuf==NULL)
{
printf("malloc(filebuf)failure");
exit
(1);
}
bnum=(filelen-1)/bsize+1;
if(Fchg32(sendbuf,FNAME,0,argv[1],(FLDLEN32)len)<0)
{
log("Fchg32(FNAME)failure\n",Fstrerror32(Ferror32));
}
printf("filelen=%ld,blocknum=%ld\n",filelen,bnum);
for(i=0;i{
if(fseek(fp,i*bsize,0)!
=0)
{
log("fseekfailure\n");
}
reallen=fread(filebuf,1,bsize,fp);
if(reallen!
=bsize&&feof(fp)==0)
{
log("fread()failure\n");
}
if(Fchg32(sendbuf,BID,0,(char*)&i,0)<0)
{
log("Fchg32(BID)failure:
%s\n",Fstrerror32(Ferror32));
}
printf("bid=%ld\n",i);
if(Fchg32(sendbuf,FDATA,0,filebuf,(FLDLEN32)reallen)<0)
{
log("Fchg32(FDATA)failure:
%s\n",Fstrerror32(Ferror32));
}
ret=tpcall("CALL",(char*)sendbuf,0,(char**)&sendbuf,&rcvlen,(long)0);
if(ret==-1)
{
log("tpcall()failure:
tperrno=%ld,errstr=%s\n",tperrno,tpstrerror(tperrno));
}
}
log("finished\n");
}
8.2异步调用方式
如图所示:
在异步请求/回答方式中,客户端使用tpacall()给本地或远程的服务器(由TUXEDO系统根据公告板信息确定)发送服务请求,与同步方式不同的是:
在此方式下,服务器处理请求时,客户端继续运行。
当客户端想得到请求的处理结果时,用tpgetrply()将结果取回。
调用过程如图:
例子:
该例子实现