0 概述
Tuxedo是类似于Message query server的一种东西,它以消息服务器的方式提供一个服务器框架,客户端向服务器发送请求报文,服务器处理之后返回应答报文。当然,服务器有对消息队列的各种管理能力。
我猜这个东西最初提供给客户的动机是为了保留客户用C开发的业务逻辑,又能方便地把自己的系统改造为面向服务的交易系统, 毕竟客户们的系统已经正常运行多年,该卖给他们一些新东西了。
因为要与C兼容,还有客户们现存应用的多样性问题,Tuxedo决定在设计上不提供消息语法与语义的支持,只是透明地转发数据块——也就是说,C语言里的char*,struct*, 甚至是void*.
于是,很多公司当时都上了当,把自己的系统改为了Tuxedo的架构,但是几乎马上的,更好的东西就出来了:jri, web service...新的服务协议都不仅提供通信层的支持,还有语法支持,有些甚至还有语义支持。杯具呀!
现在,用新技术开发的应用程序很可能会遇上需要与旧的tuxedo服务交互的要求,幸运的是,BEA提供了几种主流语言调用Tuxedo服务的技术,不幸的是,有一些很讨厌的问题存在,主要是C语言的ANSI字符集与现代语言的unicode内码的兼容问题,更别提还有utf-8这种东西……你分得清UTF8和Unicode吗?
本文说明了以C#调用Tuxedo服务的基本过程,会帮助你完成第一次Tuxedo调用。在后记中,又讨论了字符集可能会引起的问题, 希望能减少你在这条路的摸索时间。
1 安装
1.1 安装版本的选择
从BEA网站可以下载到所有版本的tuxedo服务器与客户端的安装包。我下载了V10.0 专for xp版,装在Windows Vista Professional上。
从9.1以后的客户端版本,就开始支持.net的托管代码的访问。在安装完了v10.0之后,察看了一下%TUXDIR\%bin\libscdnet.dll文件,他的版本其实还是9.1,可能在V10.0上这个托管库并没有升级。
在BEA的网站上下载完安装包之后,别忘记了在下载页面里下载许可证文件。
1.2 安装后的一些调整
1.2.1 TUXDIR环境变量的修改
我安装完成之后,客户端程序被安装在了C:\Program Files\BEA Systems\TUXEDO\tuxedo10.0_VS2005路径下,但是TUXDIR变量的设置值不知道什么原因没有指到正确的路径,而是指到了C:\Program Files\BEA Systems\TUXEDO,导致运行程序时出错,经检查C:\Program Files\BEA Systems\TUXEDO下的ULOG日志文件,报告找不到locale文件夹。我试着修改了一下TUXDIR环境变量,但没有作用。
于是把C:\Program Files\BEA Systems\TUXEDO\tuxedo10.0_VS2005\下的所有文件复制了一份到上一层的C:\Program Files\BEA Systems\TUXEDO,这个问题就解决了。
1.2.2 PATH环境变量的修改
在PATH里增加对C:\Program Files\BEA Systems\TUXEDO\tuxedo10.0_VS2005\bin目录的指向。
1.2.3 许可证文件
把下载到的许可证文件改名为lic.txt,复制到udataobj目录下。由于我们复制了安装目录,就造成了有两个这个文件夹的情况。都复制进去好了。
2 用C#写tuxedo客户端程序的基础知识
2.1 托管类的引用
%TUXDIR%/bin/libwscdnet.dll是.net2.0的托管代码类库,可以通过对这个库的引用来对tuxedo函数进行调用。当建立了一个C#客户端项目后,必须新建一个引用,选择%TUXDIR%/bin/libwscdnet.dll。其命名空间是Bea.Tuxedo;
2.2 服务器地址等环境变量的设置
根据网上的说法,有三种方法设置服务器地址:
一.用环境变量来设置:
在系统的环境变量中设置WSNADDR=//<ip address>:<port>
这样做的好处是不必在程序里配置。坏处是只支持一个服务器的连接。
二.用tuxreadenv函数
用tuxreadenv函数来从一个配置文件中读取指定的节,作为当前环境变量的设置。
如:tuxenv.ini.内容格式如下:
[TUXCOMM]
TUXDIR=c:\tuxedo
PATH=%PATH%;c:\tuxedo\bin
WSADDR=//192.168.0.1:6000
在程序中使用: tuxreadenv("tuxenv.ini","TUXCOMM");语句来调用。
在C#中,tuxreadenv函数被warp到Utils.tuxreadenv()了。
三.用tuxputenv函数inline地指定环境变量
tuxputenv函数可以在程序中直接指定环境变量。如:
tuxputenv("WSNADDR=//10.1.128.227:9401");
如果有多个环境变量要设置,可以多次调用这个函数来分别执行设置。
在C#中,tuxputenv函数被warp到Utils. tuxputenv ()了。
2.3 高版本客户端调用低于7.1版的服务器的问题
由于服务器是V6.5,而我装的客户端是10.0,因此存在一个协议兼容性的问题,在运行时报错:protocol error. 经查看ULOG文件,发现在调用7.1以下的服务器时,要设置一个环境变量WSINTOPPRE71的值为“yes”。
增加对这个环境变量设置的方法,见上节三种方法中的任何一种。
2.4 调用的一般形式
客户端调用服务的一般过程为:
设定环境变量à初始化应用上下文à调用服务à得到结果à关闭应用上下文
下面是一个最简单的C#客户端:
//设定环境变量
Utils.tuxputenv("WSNADDR=//10.1.128.227:9401");
Utils.tuxputenv("WSINTOPPRE71=yes");
//初始化应用上下文
AppContext ac = AppContext.tpinit(null);
//同步调用服务。
// 同步调用时,服务器不返回结果或是出错之前,
// tpcall方法不会返回,程序将等在这里。
TypedString sndstr = new TypedString(1000);
sndstr.PutString(0, “hello world!”);
TypedString rcvstr = new TypedString(1000);
ac.tpcall("TOUPPER", sndstr, ref rcvstr, 0);
// 得到结果
string rcvstr_str = rcvstr.GetString(0, 1000);
//关闭应用上下文
ac.tpterm();
2.5 异步调用服务
TUXEDO支持异步调用模式。在异步调用方式下,用 tpacall方式调用服务。当异步调用一个服务后,客户端程序不等服务器完成工作就立即继续执行其他工作,只保留一个句柄。等到客户端程序有空的时,再回来用tpgetrply方汉等待已经调过的服务。如下面的程序
//异步调用服务。得到异步调用描述符 acd.
AsyncCallDescriptor acd = ac.tpacall("TOUPPER", sndstr, 0);
// …. 做些其他的事情。
// 继续刚刚的服务调用,等待结果。这个方法是一个同步函数。
ac.tpgetrply(ref acd, ref rcvstr, 0);
string rcvstr_str = rcvstr.GetString();