[转帖]Tuxedo Quick Start 9 TUXEDO的缓冲区(续)_MQ, Tuxedo及OLTP讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  MQ, Tuxedo及OLTP讨论区 »
总帖数
1
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 4311 | 回复: 0   主题: [转帖]Tuxedo Quick Start 9 TUXEDO的缓冲区(续)        下一篇 
鲲鹏展翅
注册用户
等级:少校
经验:1148
发帖:79
精华:9
注册:2012-11-19
状态:离线
发送短消息息给鲲鹏展翅 加好友    发送短消息息给鲲鹏展翅 发消息
发表于: IP:您无权察看 2012-11-23 10:30:26 | [全部帖] [楼主帖] 楼主

FML(FML32)缓冲区

FML(FML32)缓冲区类似于一个表,它一般用在用在与数据库有关的操作中,如把查询结果通过FML(FML32)缓冲区发送到客户端,它有自己的一套函数对其进行操作。FML(FML32)在发送时,只发送真正用到的数据,这一点与其他的类型的缓冲区不一样。如分配的缓冲区大小为1M,但真正用到的空间只有1K,那么在发送时只发送这1K数据,如果时其他类型的缓冲区时也是发送1M的数据。它的使用方式和VIEW差不多,说明如下:(最大为4G)

1.        定义FML(FML32)的描述文件,如定义名为demo.fml的描述文件如下,假设该文件在D:\DEMO目录下。

*base        1000
# name number type     flags comments
EMPNO           1        long                -                -
ENAME           2        string            -                -
PHOTO           3        carray     -            “store the photo data”
SAL               4        double      -            -


定义一个FML(FML32)文件类似于定义一张表,各个字段的含义如下:
type:    该字段的类型, 可以为short, char, long, float, double,STRING ,CARRAY.
         注意: STRING,CARRAY要用小写。
name:    该字段的名字
number:  该字段的ID号,在一个FML(FML32)的定义文件中要唯一,
         0-100, 6000-7000归TUXEDO系统内部用,
FML的范围是101–8191,
         FML32的范围是101 -33,554,431。
Flag:     设置该字段的一些标志
comments: 对该字段的注释

*base: 字段的ID号的起始值,真正的值*base加上number的值
$:    注释,并且出现在生成的*.h文件中
#:    注释,不出现在生成的*.h文件中
“-”:表示该属性采用默认值.

2.        用mkfldhdr或mkfldhdr32进行编译,生成对应的*.h文件,如于上面的定义相对应的
*.h文件用mkfldhdr32 demo.fml32命令编译,生成demo.fml32的内容如下:

/*      fname   fldid            */
/*      -----   -----            */
#define EMPNO   ((FLDID32)33555433)     /* number: 1001  type: long */
#define ENAME   ((FLDID32)167773162)    /* number: 1002  type: string */
#define PHOTO   ((FLDID32)201327595)    /* number: 1003  type: carray */
#define SAL     ((FLDID32)134218732)    /* number: 1004  type: double */


3.        定义环境变量FIELDTBLS (FIELDTBLS32), FLDTBLDIR (FLDTBLDIR32)
4.        FLDTBLDIR (FLDTBLDIR32): FML(FML32)的定义文件所在的路径
FIELDTBLS (FIELDTBLS32): FML(FML32)的定义文件名,如果有多个用,隔开
如对上面的demo.fml32文件为:

SET FLDTBLDIR32=D:\DEMO
SET FIELDTBLS32= demo.fml32


5.        在使用到该FML(FML32)的程序中用#include包含生成的*.h文件.并要包含fml.h
fml32.h文件。
6.在程序中通过FML(FML32) 函数对FML(FML32)缓冲区进行操作

FML与FML32的区别:
FML与FML32相类似,区别在于:
1.        FML32中使用32位的数表示字段的ID和该字段的长度,FML32中使用16位的数表示字段的ID和该字段的长度,所以FML32能表示更大的缓冲区。
2.        对FML32的操作函数都以32结尾。 环境变量也以32结尾。

常用的FML(FML32)操作函数:
FML(FML32)采用自己单独的一套函数对FML(FML32)缓冲区进行操作。FML32的操作函数
与FM的操作函数一样,只是以32结尾,所以下面只说明常用的FML函数

FBFR*  Falloc (FLDOCC F, FLDLEN V)


描述: 分配一块FML缓冲区
参数:
    FLDOCC: 该FML缓冲区的字段个数,
    FLDLEN: 该FML缓冲区的长度
返回值:成功返回一个指向该FML缓冲区首地址的指针,失败返回NULL,错误号保存在全局
变量Ferror中
注意:   该FML缓冲区不能用于TPCALL(),TPACALL(),TPRETURN()等中,在这些函数中用到
的FML缓冲区只能用TPALLOC()分配。

int Finit(FBFR *fbfr, FLDLEN buflen)


描述: 初始化该FML缓冲区
参数:
   fbfr: 一个指向该FML缓冲区首地址的指针
   buflen: 该FML缓冲区的长度
返回值:失败为-1, 错误号保存在全局变量Ferror中

int Fadd(FBFR *fbfr, FLDID fieldid, char *value, FLDLEN len)


描述: 往FML缓冲区fbfr中ID为fieldid的字段增加一个值value
参数:
fbfr:    指向该FML缓冲区首地址的指针
fieldid: 要增加的字段的ID
value:   要增加的值,如果时其他类型的要转化为char *
len:     该字段的长度,如果不时CARRARY类型的,可设为0
返回值: 失败为-1, 错误号保存在全局变量Ferror中

int Fchg(FBFR *fbfr, FLDID fieldid,int occ, char *value, FLDLEN len)


描述: 改变fbfr中ID为fieldid字段的值。
参数:
fbfr:    指向该FML缓冲区首地址的指针
fieldid: 要增加的字段的ID
value:   该字段的新值,如果时其他类型的要转化为char *
len:     该字段的长度,如果不时CARRARY类型的,可设为0
返回值:失败为-1,错误号保存在全局变量Ferror中

int Fget(FBFR *fbfr, FLDID fieldid,int occ, char *value, FLDLEN *maxlen)


描述: 从fbfr缓冲区中取ID为fieldid字段的值到value中。
参数:
fbfr:    指向该FML缓冲区首地址的指针
fieldid: 字段的ID
value:   取出的值保存到该指针指向的地址中
maxlen:  可以COPY到缓冲区value中的字符串的长度,返回值为真正COPY到该缓冲区的字
符串的长度
返回值:失败为-1, 错误号保存在全局变量Ferror中

Fprint(FBFR *fbfr)


描述: 按格式打印fbfr缓冲区的内容。一般用于程序调试中。
参数:
fbfr:    指向该FML缓冲区首地址的指针
返回值:失败为-1, 错误号保存在全局变量Ferror中

Ferror:


和C语言中的errno类似,当调用FML(FML32)函数出错时,把错误号保存在全局变量Ferror中。

char *  Fstrerror(int err)


描述:返回错误号为err的错误描述
参数:err: Ferror的值
返回值:成功返回错误描述,失败返回NULL

XML缓冲区

从TUXEDO7.1开始,TUXEDO支持XML缓冲区,并可根据XML中某个ELEMENT(元素)的值,ELEMENT的类型,或ATTRIBUTE(属性)的值实现数据依赖路由。同CARRAY一样,在对XML缓冲区进行操作时要指定缓冲区的长度。
在TUXDO7.1中内置了XML PARSER,它主要完成以下工作:
1.        自动检测XML缓冲区所采用的字符集。
2.        如果XML缓冲区所采用的字符集不是ASCII或 EBCDIC字符集,把ELEMENT,ATTRIBUTE的名字转换为ASCII或 EBCDIC。
3.        检查缓冲区中ELEMENT的内容,ATTRIBUTE的值。
4.        数据类型转换,在数据依赖路由中,如果是采用XML类型,要指定所采用的路由字段的数据类型,XML只支持字符型的数据,如果路由字段是数字型的,将自动进行类型转换。

例子:
用户的定单保存成XML文件形式,定单的格式都一样,但预定不同的产品要进行不同的处理,或要保存到不同的数据库中,如定单号为1-9999的是购买衬衫的,要保存到数据库1中,定单号为10000-19999是购买鞋的,要保存到数据库2中,其它的定单保存到数据库3中。
可采用数据依赖路由来实现这样的功能,
客户端程序读取这些XML文件,并调用服务ORDER处理这些定单,TUXEDO服务器根据收到的XML缓冲区中的定单号ORDERNO的值,把请求路由到不同的GROUP进行处理。定单号为1-9999路由到GROUP1(对应数据库1),定单号为10000-19999路由到GROUP2(对应数据库12),其他的定单则路由到GROUP3(对应数据库3)。

定单的XML文件格式如下:

<?xml version="1.0" encoding="UTF-8"?>
<ORDER>
<HEADER DATE="03/16/2000" ORDERNO="12345"/>
<COMPANY>ACME</COMPANY>
<ITEM BRAND="CALVIN KLEIN" SIZE="16,32" COLOR="WHITE" QUANTITY="15">SHIRTS</ITEM>
</ORDER>


配置文件的内容

*RESOURCES
IPCKEY                61234
MASTER                simple
MAXACCESSERS        100
MAXSERVERS        50
MAXSERVICES        100
MODEL                SHM
*MACHINES
MYSERVER        LMID=simple
TUXCONFIG="D:\tuxdemo\xml\tuxconfig"
TUXDIR="d:\bea\tuxedo7.1"
APPDIR="d:\tuxdemo\xml"
*GROUPS
GROUP1                LMID=simple        GRPNO=1
TMSNAME="TMS_ORA8i"        TMSCOUNT=2
OPENINFO="Oracle_XA:Oracle_XA+Acc=P/scott/tiger+SesTm=600+MaxCur=5+LogDir=."
GROUP2                LMID=simple        GRPNO=2
TMSNAME="TMS_INFORMIX" TMSCOUNT=2
OPENINFO="INFORMIX:mydb2"
GROUP3                LMID=simple        GRPNO=3
TMSNAME="TMS_INFORMIX" TMSCOUNT=2
OPENINFO="INFORMIX:mydb3"
*SERVERS
DEFAULT:
CLOPT="-A"
shirtorder        SRVGRP=GROUP1        SRVID=9
shoeorder        SRVGRP=GROUP2        SRVID=10
otherorder        SRVGRP=GROUP3        SRVID=11
*SERVICES
ORDERSVC        LOAD=50        PRIO=50                ROUTING=ORDERNO
*ROUTING
ORDERNO                FIELD="ORDER/HEADER/@ORDERNO"
BUFTYPE="XML"
RANGES="1-9999:GROUP1,
10000-19999:GROUP2,
*:GROUP3"


客户端程序orderclt.c的内容:

#include <stdio.h>
#include "atmi.h" /* TUXEDO Header File */
#define MAXXMLDOCSIZE 4096 /* Max XML doc size */
main(int argc, char *argv[])
{
      char *sendbuf, *rcvbuf;
      long sendlen, rcvlen;
      int ret;
      FILE *xml_fd;
      char xml_file[256];
      char *xml_buffer;
      int nsize;
      if(argc != 2)
      {
            printf("Usage: %s <XML-doc-file>\n", argv[0]);
            exit(1);
      }
      /* Read the XML document in first */
      strcpy(xml_file, argv[1]);
      if ((xml_fd = fopen(xml_file, "r")) == NULL)
      {
            printf("fopen(%s) fail\n", xml_file);
            exit(1);
      }
      if ((xml_buffer = (char *)malloc(sizeof(char) * MAXXMLDOCSIZE)) == NULL)
      {
            printf("malloc failed for XML doc\n");
            exit(1);
      }
      if ((nsize = fread(xml_buffer, sizeof(char), MAXXMLDOCSIZE, xml_fd)) < 0)
      {
            printf("fread(%s) fail\n",xml_file);
            exit(1);
      }
      /* Attach to System/T as a Client Process */
      if (tpinit((TPINIT *)NULL) == -1)
      {
            printf("tpinit() fail: %s\n", tpstrerror(tperrno));
            exit(1);
      }
      /* Allocate XML buffers for the request and the reply */
      sendlen = strlen(xml_buffer);
      if((sendbuf = (char *) tpalloc("XML", NULL, sendlen+1)) == NULL)
      {
            printf("tpalloc(sendbuf) fail:%s\n",tpstrerror(tperrno));
            tpterm();
            exit(1);
      }
      if((rcvbuf = (char *) tpalloc("XML", NULL, sendlen+1)) == NULL)
      {
            printf("tpalloc(sendbuf) fail:%s\n",tpstrerror(tperrno));
            tpfree(sendbuf);
            tpterm();
            exit(1);
      }
      (void)strcpy(sendbuf, xml_buffer);
      /* Request the service ORDERSVC, waiting for a reply */
      ret = tpcall("ORDER", (char *)sendbuf, sendlen, (char **)&rcvbuf, &rcvlen, 0);
      if(ret == -1)
      {
            printf("tpcall(ORDERSVC) fail:%s",tpstrerror(tperrno));
            tpfree(sendbuf);
            tpfree(rcvbuf);
            tpterm();
            exit(1);
      }
      printf("Returned string is: %s\n", rcvbuf);
      /* Free Buffers & Detach from System/T */
      tpfree(sendbuf);
      tpfree(rcvbuf);
      tpterm();
}


服务端程序order.c

#include <stdio.h>
#include <atmi.h> /* TUXEDO Header File */
#include <userlog.h> /* TUXEDO Header File */
ORDER(TPSVCINFO *rqst)
{
      userlog("ORDER xml data: %s", rqst->data);
      /*把定单保存到数据库中,程序省略*/
      。。。。。。。。。
      tpreturn(TPSUCCESS, 123, rqst->data, rqst->len, 0);
}


把order.c编译为shirtorder和shoeorder两个SERVER

buildserver -o shirtorder -f order.c -s ORDER
buildserver -o shoeorder -f order.c -s ORDER


运���程序:

orderclt test.xml


如果test.xml中ORDERNO的值为1-9999路由到GROUP1,为10000-19999路由到GROUP2,其他的定单则路由到GROUP3。




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