在server端tuxedo本身提供了一个标准的main()函数,它负责完成一些必要的工作。server端编程只需要编写service处理函数,进行service的请求处理和回应处理。所以,在server端不需要调用tpinit()和tpterm()。
只有一个参数,该参数是指向TPSVCINFO结构的指针(atmi.h)。该结构定义如下:
struct tpsvcinfo {
char name[32]; /*service名(最大15个字符)*/
long flags; /* client调用时指定的flags */
char *data; /* 接收的数据地址 */
long len; /* 数据长度 */
int cd; /* 会话方式下的连接描述符 */
long appkey; /* 应用认证的key */
CLIENTID cltid; /* client ID */
};
通过TPSVCINFO参数传递的buffer是使用tpalloc()分配的,所以可以对它使用tprealloc()。
要注意的是在service函数里自己调用tpalloc()分配的空间在退出要释放,除非该空间作为tpreturn()或tpforward()的参数。如果分配的空间不释放,最终会耗尽该server的内存资源。
对于TPSVCINFO传递的buffer不用手动释放。
使用举例:
void
BAL (TPSVCINFO* input)
{
char* f, f1, f2;
f=input->data;
f1=tpalloc (“STRING”, NULL, 80);
f2=tpalloc (“STRING”, NULL, 120);
. . .
tpfree ((char *) f2);
tpreturn (TPSUCCESS, 0, f1, 0, 0);
}
可以使用tptypes()查看buffer的类型。如:
void ABAL(TPSVCINFO *transb)
{
char type[20], subtype[20];
long len;
len = tptypes(transb->data, type, subtype);
if (len == 0) {
/*error*/
userlog(“NULL message sent...\n”);
...
}
if (strcmp(type, “FML”) == 0) {
/* convert FML to aud VIEW; */
} else if (strcmp(type, “VIEW”) == 0) {
if (strcmp(subtype, “aud”) != 0) {
/*error*/
userlog(“Wrong VIEW subtype...”);
...
}
} else {
/*error*/
userlog(“Invalid buffer type ...”);
...
}
}
这样做时有一些情况要注意:
int tpadvertise (char *svcname, void (*func)(TPSVCINFO *));
参数说明:
svcname:要发布的service名;
func:该service对应的处理函数指针;
如果该service用func已经发布,则函数立即成功返回。如果调用server是MSSQ集的一员,则该MQSQ中的所有server都发布这个service。失败时返回-1。
出错原因:
int tpunadvertise (char *svcname);
参数说明:
svcname:操作的service名;
如果调用server是MSSQ集的一员,则该MQSQ中的所有server都取消发布这个service。失败时返回-1。
失败原因:
void tpreturn(int rval, int rcode, char *data,long len, long flags);
参数说明:
rval:返回值,决定该service请求是否成功。如三个可选值:
void tpforward(char *service, char *data, long len, long flags);
参数说明:
service:后续的service的名称;
data:指向传递的buffer的指针;
len:buffer的长度(只CARRAY有用);
flags:当前没有使用;
该函数不能用在会话service中。
int tpsvrinit(int argc, char **argv);
参数说明:形式类似与main函数的参数,函数里可以使用getopt和全局变量optind进行处理,配置文件中的CLOPT命令行选项也传递到该函数。
函数成功返回0,失败返回-1。
void tpsvrdone();