tuxedo服务封装

合集下载

最新weblogic与tuxedo配置详解

最新weblogic与tuxedo配置详解

一、WTC配置步骤:1. Tuxedo的配置2.1.1. 设置环境变量:2.1.3. 配置ubbconfigMASTER simpleMAXACCESSERS 50MAXSERVERS 50MAXSERVICES 50MODEL SHMLDBAL N*MACHINESDEFAULT:APPDIR="c:\tuxedo_test\simpapp"TUXCONFIG="c:\tuxedo_test\simpapp\tuxconfig"TUXDIR="c:\bea\tuxedo8.1"#Example:# APPDIR="/home/me/simpapp"# TUXCONFIG="/home/me/simpapp/tuxconfig"# TUXDIR="/usr/tuxedo"VM44 LMID=simpleMAXWSCLIENTS=5 #指定的最大客户端连接数#Example:#beatux LMID=simple*GROUPSGROUP1 LMID=simple GRPNO=1 OPENINFO=NONEJSLGRP LMID=simple GRPNO = 2JREPGRP LMID=simple GRPNO = 3GROUP4 LMID=simple GRPNO=4 OPENINFO=NONE*SERVERSDEFAULT:CLOPT="-A"simpserv SRVGRP=GROUP1 SRVID=1WSL SRVGRP=GROUP1 SRVID=5 CLOPT="-A -t -- -n //192.168.57.41:8888 -m 2 -M 5 -x 10" #WSL发布地址JREPSVR SRVGRP=JREPGRP SRVID=10 CLOPT="-A -- -W -PC:\bea\tuxedo8.1\udataobj\jolt\repository\jrepository"红色为jolt服务需要的配置,jolt需要单独的license。

TUXEDO中间件介绍及应用

TUXEDO中间件介绍及应用

TUXEDO中间件介绍及应用TUXEDO(Tuxedo Extended Distributed Object)是一种中间件技术,用于分布式应用程序的开发和管理。

它在1980年代初由AT&T Bell Laboratories开发,旨在帮助开发人员构建可靠的、复杂的分布式应用程序。

TUXEDO的主要特点是具有高度可伸缩性和可靠性。

它采用了基于事务的处理模型,在分布式环境中管理事务处理非常重要。

TUXEDO使用一种称为QT(Queueing and Transaction)的机制来处理事务,它能够确保在分布式环境中的多个服务器之间的事务一致性。

TUXEDO提供了一个面向服务的架构,允许开发人员将应用程序划分为一系列可重用的服务。

这些服务被封装在名为“服务进程(service processes)”的单独运行实体中。

TUXEDO还提供了一个名为“Bulletin Board”的中央注册表,用于跟踪可用服务的位置和状态。

通过这种方式,开发人员可以根据需要动态添加或删除服务,而不会中断正在运行的应用程序。

除了事务管理和服务管理功能外,TUXEDO还提供了一些其他的功能,使开发人员能够更轻松地开发和管理分布式应用程序。

例如,它提供了监视和诊断工具,用于跟踪应用程序的性能和健康状况。

它还提供了故障恢复功能,可以在节点失败时自动重启或迁移服务。

TUXEDO中间件在许多行业中得到广泛应用,尤其是那些需要构建高可靠性和高性能的分布式应用程序的领域。

例如,金融领域的交易处理系统、电信领域的网络管理系统以及电子商务领域的订单处理系统等都可以使用TUXEDO来实现。

总之,TUXEDO是一种先进的中间件技术,用于构建和管理复杂的分布式应用程序。

它提供了高度可伸缩和可靠的处理模型,支持事务管理、服务管理和分布式锁等强大功能。

它在各种行业中得到广泛应用,特别是那些需要高可靠性和高性能的应用程序领域。

BEA中间件Tuxedo介绍

BEA中间件Tuxedo介绍
全国IISP平台的唯一技术平台产品
Page 10
WebLogic Platform
BEA WebLogic Workshop IDE
BEA WebLogic Portal Liquid Data BEA WebLogic Integration
Portal Foundation
Services
Interaction Intelligent
应用 Tux
EXEC SQL select * from..
业务逻辑
在服务
应用 Tux
数据库 器应用 服务器 种的
SQL
数据访问
基于服务的应用是无连接的
客户 端应 用种 的
SQL
EXEC SQL select from..;
应用
表达服务
SQL 连接
NN
事务
NN
断开连接 NN
业务逻辑
数据库 服务器
数据访问
Page 8
BEA技术类合作伙伴
Administration & Management Integration
Security Development &
Deployment
Portal
hp OpenView
Page 9
BEA @ China
80%+省本地网计费系统、客服系统、中国电信VNET 北京电信EAI、苏州电信EAI、北方9省网上营业厅 甘肃、重庆、福建(泉州)、深圳新97系统
Tuxedo在世界级企业 关键性系统的应用
150 million transactions daily to deliver 3 million packages
10,000 transactions per second to transact over $1 trillion annually

封装服务

封装服务

封装服务主要是指为某些功能或操作提供对外的接口,从而可以让远方的程序进行调用。

在服务代码中,可以自己编写业务逻辑,也可以调用已经编写好的JavaBean。

我们主要采用中间件GDT(Grid Development Tools)开发服务,GDT可以简化开发流程。

利用它我们可以方便的实现Stub类的生成、gar包的生成以及服务的本地部署。

安装以及基本的使用方法见http://mage.uni-marburg.de/trac/gdt/wiki。

一、封装资源为服务在结构工程网格中,所有的资源必须以网格服务的形式存在。

因此,对资源的服务化封装是一个必须且重要的环节。

到目前为止,已经顺利将结构工程网格中的现有数据资源以及针对此数据资源的几个数据查询操作封装为网格服务,并能够从Portal处进行调用。

需要说明的是,我们实现的是从异地对网格服务进行调用。

网格服务的开发原理和部署过程都是类似的。

图3.2说明了在网格环境下开发网格服务的流程:图3.2 网格服务开发流程图1.1、将数据资源代理的业务逻辑打为war包由于是对数据资源进行异地封装且开发环境存在较大差异,因此在进行封装之前,需要将原有工程打为war包并重新配置开发环境。

这是统一开发环境的过程,其具体的操作过程如下所示:1、右键点击所要打包的工程,如图3.2.1[1]界面,选择其中的Export项。

选择此项图3.2.1[1]2、选择将要生成的文件为war文件,点击Next,如图3.2.1[2]所示。

图3.2.1[2]3、选择要打为war包的工程,并确定生成的war文件的输出路径,点击Finish,如图3.2.1[3]所示。

图3.2.1[3]4、为了便于重新配置开发环境,将wenesesgrid.war传送到信息服务小组并进行解压。

5、将wenesesgrid.war解压后生成的所有的jar文件拷贝到GT4的容器中去,具体位置是/usr/local/globus-4.0.5/lib。

中间件技术-BEA Tuxedo在金融业跨行实时业务中的应用

中间件技术-BEA Tuxedo在金融业跨行实时业务中的应用

第28卷湖北师范学院学报(自然科学版)Vol128第4期Journa l of Hube i Nor m al University(Na t ural Science)No14,2008中间件技术-BEA Tuxedo在金融业跨行实时业务中的应用丁小进1,徐江焱2(1.中国建设银行信息技术管理部,湖北武汉430015;2.黄石市环境保护局,湖北黄石435000)摘要:B E A Tuxedo中间件基于三层应用结构的设计理验,实现异构平台之间的数据交换,能满足业务交易并发的需求。

提出了跨商业银行实时业务设计中的难点问题,用实例说明了Tuxed o中间件技术在解决多个异构平台之间的通讯问题和封装业务逻辑、建立组件化模型的优势。

关键词:中间件;B E A Tuxedo;实时业务中图分类号:TP151 文献标识码:A 文章编号:100922714(2008)03200542040 前言 自2006年以来,中国人民银行为了加快现代化支付系统的建设,进一步改善个人支付结算业务,要求商业银行依托小额支付系统,实现商业银行间的跨行通存通兑等实时业务。

本人作为某商业银行的技术骨干,在该项目的开发工作中担任需求分析、总体设计和部分代码的编写工作。

由于开通跨行通存通兑业务需要经过商业银行行内系统的多个节点通过与人民银行的互连,实现与其他商业银行系统的数据交互。

系统需要跨越各种异构平台,保证实时交易的完整性,因此解决好各个节点间的通讯问题和理清业务处理流程就显得尤为重要。

目前在大型计算机应用系统中,中间件的使用日益普及,B EA Tuxedo中间件作为最优秀的中间件产品,便于实现业务逻辑的封装、建立分布式事务管理的组件化模型,能够对应用系统的开发、调度和操作提供结构化的设计方案,具有跨越不同异构平台的优点,因此在项目开发中选用了Tuxedo中间件。

1 基本工作原理 Tuxedo是BEA公司的交易中间件产品,1984年由贝尔实验室开发成功,1992年易主Novell公司,1996年由BEA公司收购,经过十多年的不断更新和完善,Tuxedo已经发展成为交易中间件领域事实上的标准。

TUXEDO配置参数详解

TUXEDO配置参数详解

TUXEDO配置参数详解2007-07-10 09:39:47大中小TUXEDO应用系统的配置3.1 TUXEDO应用系统的常见配置配置文件UBBCONFIG介绍一个TUXEDO应用系统的所有资源都在一个文本文件中进行定义,该文件称为UBBCONFIG,在配置完成后,UBBCONFIG被编译成一个二进制的文件TUXCONFIG.在TUXEDO系统启动时,从该文件中读取系统的配置信息。

UBBCONFIG文件类似WINDOWS下的*.INI文件。

它包括以下9大部分, 我们称之为节,RESOURCES,MACHIENS,GROUPS这三个节必须的,其他的节是可选的。

RESOURCES(必需): 与整个系统有关的配置信息MACHINES(必需): 一个TUXEDO应用系统可以跨越多台服务器,在该节中配置与每台服务器有关的信息GROUPS(必需): TUXEDO中的服务可被分为多个组,在该节中配置与组有关的信息SERVERS(可选): 与SERVER有关的信息在该节配置SERVICES(可选): 与SERVICES有关的信息在该节配置NETWORK(可选):与网络有关的信息在该节配置ROUTING(可选) :路由规则在该节配置NETGROUPS(可选):与网络分组有关的信息在该节配置名称解释:TUXEDO应用系统一个TUXEDO应用系统包括服务端,客户端,服务端安装在服务器上,客户端一般安装在PC 机上,从开发角度看,一个TUXEDO应用系统包括服务端程序,客户端程序,一个配置文件。

此外,一个TUXEDO应用系统可以部署在一台服务器上,也可以部署在多台服务器上。

SERVER:服务端程序用C或COBAL编写,每一个程序文件编译成一个相应可执行文件,该可执行文件在运行时称为SERVER,它实际上就是一个进程。

每个SERVER都有一个名字,也就是该进程的名字。

为与TUXEDO应用系统的服务端区分,我们在本书中,我们用SERVER表示该进程,用服务端表示TUXEDO应用系统的服务端。

tuxedo应用

tuxedo应用

*GROUPS
*GROUPS "LDMGRP" LMID="SITE1" GRPNO=20 TMSCOUNT=3 //组名,所属主机,组号,TMS个数(事 务监控) "LGWGRP01" LMID="SITE1" GRPNO=101 TMSCOUNT=3 "TRAN0" LMID="SITE1" GRPNO=50 TMSCOUNT=3 "THR990" LMID="SITE1" GRPNO=92 TMSCOUNT=3 "MUTIPAGE_GROUP" LMID="SITE1" GRPNO=100 TMSCOUNT=3 "RMS_GROUP" LMID="SITE1" GRPNO=200 TMSCOUNT=3 "POS_CTL_GRP" LMID="SITE1" GRPNO=300 TMSCOUNT=3
详解命令行参数
-A 表示server启动时,自动在BB中登记所包含的services。 -t 低版本的客户端连高版本的server端 -n 接入点为 HOST/IP:PORT, 与客户端WSNADDR环境变量相同。 -m 表示这个JSL fork出最少的JSH个数(初始值) -M 表示这个JSL fork出最多的JSH个数 -x 表示每个JSH同时处理多少各client的连接。 (请求队列的长度) -T 表示client端连上server连接后, 如果30秒没有交易请求,自动关闭连接。 -H 使用防火墙的外网地址。 -p -P 防火墙接入点所用的端口号范围。 (客户端WSNADDR要与外网地址一样)

使用C++ Builder封装Tuxedo客户端调用

使用C++ Builder封装Tuxedo客户端调用

使用C++ Builder封装Tuxedo客户端调用本文主要介绍如何使用C++ Builder把Tuxedo客户端的调用封装成一个独立的类CTuxCall,最大程度的方便用户调用tuxedo,并给出相应的例子,以供参考.由于是第一次发表这样的文章,其中不足之处,还望大家予以批评指正。

类CTuxCall的特点封装后的类CTuxCall有如下一些特点,能够最大程度的满足用户的需求,方便用户的调用. (1) 可以自定义连接方式,长连接,短连接和混合连接(由用户自定义连接次数,当实际的连接次数超过自定义的连接次数,则自动断开连接,然后重连);(2) 可以自动切换连接地址,目前提供了5个备用地址,只要其中有一个地址上的服务是正常的,则Tuxedo的连接就是正常的;(3) 能够方便的设置客户端的信息,如操作员名称,操作员IP地址,或者操作员当前操作状态;(4) 调用方式简单,灵活,可扩充性好.类CTuxCall函数说明(1) 设置客户端信息,在这里你可以设置操作员或者终端,甚至是一些操作状态的信息:void SetClientInfo(char* username,char* ctlname);使用该函数后,在服务器的管理平台,使用pclt命令,就会显示客户端的相关信息,如:LMID User Name Client Name Time Status Bgn/Cmmt/Abrt--------------- --------------- --------------- -------- ------- -------------szx1app tuxedo WSH 21:54:08 IDLE 0/0/0szx1app oper01 192.168.1.114 0:18:15 IDLE/W 0/0/0(2) 设置连接方式: bool SetConnectType(int contype);(3) 设置监听地址: bool SetWSNAddr(char* addrlist);参数格式如下:"//ip1:port1;//ip2:port2;....;//ip5:port5" ,最多支持5个IP地址.(4) 服务调用: Invoke();在客户端编写代码,只要调用这个函数即可.关于这个函数有几个不同的函数原形,具体如下:bool Invoke(char * OpCode,...);指定操作码,调用确省服务,参数个数不定,至于如何把传入的参数一定的格式写入到发送缓冲去,需要调用自定义的函数进行打包.bool Invoke(char* SrvName,char* OpCode,...);大体内容同上,只是调用的是指定的服务,而不是确省的服务.bool Invoke(char* SrvName,long InLen,long &OutLen);在使用此函数之前,必须保证先调用SetSendBuf()函数填充发送缓冲区.bool Invoke(char * SrvName,char * InStr,long InLen, char * &OutStr, long &OutLen,int flag = 0); 调用指定服务,输入参数和返回结果都由用户自定.(5) 填充发送缓冲区:int SetSendBuf(char *szFormat,...);该函数用法同c语言的printf()函数,只是发送缓冲区的长度有限制,最好不要超过1024*10个字节.源码分析类CTuxCall的源码TuxCall头文件//---------------------------------------------------------------------------#ifndef TuxCallH#define TuxCallH//---------------------------------------------------------------------------#if defined(__BORLANDC__)&&!defined(SOCKET_CONNECT)//#pragma comment (lib,"libtux.lib")//#pragma comment (lib,"libbuft.lib")//#pragma comment (lib,"libfml.lib")//#pragma comment (lib,"libfml32.lib")//#pragma comment (lib,"libengine.lib")#endif#define TRANSMITER "TRANSMIT"class CTuxCall{private:char * m_RecBuff;char * m_SendBuff;char ErrMsg[1024];void ClearBuffer();int m_Errno;bool m_bBeginTrans;int m_ConnectionType; //连接方式:0:长连接,1:短连接;m(m>10):m次调用后自动断开连接,并自动重连int m_ConCount; //服务调用计数器char m_UserName[64];char m_CtrName[64];char m_WSNAddrList[5][64];char m_CurWSNADDR[64];bool m_bInConnection; //是否正处在连接之中bool CheckWSNADDRValid(char* ipstr,char* port);char * GetErrMsg(char * ATitle,char * AMsg="");bool AllocSrc(int size);bool AllocDest(int size);char m_EscapeFlag;int m_Col; //返回结果每条记录的字段数long m_Row; //返回结果的记录数char m_ColSep[5]; // 字段间的分隔符char m_RowSep[5]; // 记录间的分隔符public:CTuxCall();~CTuxCall();void SetClientInfo(char* username,char* ctlname);bool SetConnectType(int contype);bool SetWSNAddr(char* addrlist);// addrlist="//ip1:port1;//ip2:port2;....;//ip5:port5" 最多支持5个IP地址.void Disconnect();bool Invoke(char * SrvName,char * InStr,long InLen, char * &OutStr, long &OutLen,int flag = 0); bool Invoke(char * OpCode,...);bool Invoke(char* SrvName,char* OpCode,...);bool Invoke(char* SrvName,long InLen,long &OutLen);bool BeginTransaction(unsigned long timeout=120);bool Rollback();bool Commit();bool TuxInit();bool TuxTerm();char *GetErrorMessage();char *GetCurWSNAddr();char *GetResultData();int SetSendBuf(char *szFormat,...); //总字符串的长度不超过1024*10个字节.};#endifCTuxCall的实现#pragma hdrstop#include "TuxCall.h"#ifndef _TM_WIN#define _TM_WIN#endif#include "atmi.h"#include "stdio.h"#include#include#ifndef _NOAUTOLIB#ifndef _NOAUTOMSG#pragma message( "Will automatically link with libbuft.lib" )#endif#pragma comment(lib, "libbuft.lib")#ifndef _NOAUTOMSG#pragma message( "Will automatically link with libnwi.lib" )#endif#pragma comment(lib, "libnwi.lib")#ifndef _NOAUTOMSG#pragma message( "Will automatically link with libnws.lib" )#endif#pragma comment(lib, "libnws.lib")#ifndef _NOAUTOMSG#pragma message( "Will automatically link with libwsc.lib" )#endif#pragma comment(lib, "libwsc.lib")#ifndef _NOAUTOMSG#pragma message( "Will automatically link with libfml.lib" ) #endif#pragma comment(lib, "libfml.lib")#ifndef _NOAUTOMSG#pragma message( "Will automatically link with libfml32.lib" ) #endif#pragma comment(lib, "libfml32.lib")#ifndef _NOAUTOMSG#pragma message( "Will automatically link with libgp.lib" )#endif#pragma comment(lib, "libgp.lib")#endif//--------------------------------------------------------------------------- CTuxCall::CTuxCall(){m_bBeginTrans = false;m_ConnectionType = 0;m_ConCount = 0;m_bInConnection = false;memset(m_WSNAddrList,0,sizeof(m_WSNAddrList));m_RecBuff=NULL;m_SendBuff=NULL;m_Row =0;m_Col =0;m_EscapeFlag = "\\";memset(m_ColSep,0,sizeof(m_ColSep));strcpy(m_ColSep,"~#~");memset(m_RowSep,0,sizeof(m_ColSep));strcpy(m_RowSep,"`^`");}CTuxCall::~CTuxCall(){if(m_RecBuff)tpfree(m_RecBuff);if(m_SendBuff)tpfree(m_SendBuff);tpterm();m_RecBuff = NULL;m_SendBuff = NULL;}char * CTuxCall::GetErrMsg(char * ATitle,char * AMsg){if(strlen(AMsg)!=0)sprintf(ErrMsg,"%s\n错误代码:%d\n错误信息:%s",A Title,m_Errno,AMsg);elsesprintf(ErrMsg,"%s\n错误代码:%d\n错误信息:%s",A Title,tperrno,tpstrerror(tperrno)); return ErrMsg;}bool CTuxCall::SetWSNAddr(char* addrlist){//addrlist的格式: //IP1:PORT1;//IP2:PORT2;//IP3:PORT3;.....char tmpAddr[64*5]={0};char ipstr[32]={0};char port[16]={0};int nPos = 0;int iPos = 0;char *ptr=NULL;memset(m_WSNAddrList,0,sizeof(m_WSNAddrList));memset(tmpAddr,0,sizeof(tmpAddr));strncpy(tmpAddr, addrlist,64*5);int i=0;while (i<5){ptr = strstr(tmpAddr,";");if (ptr){nPos = ptr - tmpAddr;memset(m_CurWSNADDR,0,sizeof(m_CurWSNADDR));strncpy(m_CurWSNADDR,tmpAddr,nPos);//strncpy(tmpAddr,ptr+1,strlen(ptr+1));//tmpAddr[strlen(ptr+1)-nPos]="\0";strcpy(tmpAddr,ptr+1);ptr = strstr(m_CurWSNADDR,":");if (ptr){iPos = ptr - m_CurWSNADDR ;memset(ipstr,0,sizeof(ipstr));memset(port,0,sizeof(port));if (m_CurWSNADDR[0]=="/"&&m_CurWSNADDR[1]=="/"){strncpy(ipstr,m_CurWSNADDR+2,iPos-2);strncpy(port,ptr+1,strlen(ptr+1));}else{strncpy(ipstr,m_CurWSNADDR,iPos);strncpy(port,ptr+1,strlen(ptr+1));if (CheckWSNADDRValid(ipstr,port)){strncpy(m_WSNAddrList[i],m_CurWSNADDR,strlen(m_CurWSNADDR)); i++;}else{m_Errno = -28;GetErrMsg("参数设置错误","WSNADDR的IP地址或者监听端口无效."); return false;}}else{m_Errno = -28;GetErrMsg("参数设置错误","WSNADDR的IP地址或者监听端口无效."); return false;}}else{//IP5:PORT5ptr = strstr(tmpAddr,":");if (ptr){iPos = ptr-tmpAddr ;memset(ipstr,0,sizeof(ipstr));memset(port,0,sizeof(port));if (tmpAddr[0]=="/"&&tmpAddr[1]=="/"){strncpy(ipstr,tmpAddr+2,iPos-2);strncpy(port,ptr+1,strlen(ptr+1));}else{strncpy(ipstr,tmpAddr,iPos);strncpy(port,ptr+1,strlen(ptr+1));}if (CheckWSNADDRValid(ipstr,port)){strncpy(m_WSNAddrList[i],m_CurWSNADDR,strlen(m_CurWSNADDR)); break;}{m_Errno = -28;GetErrMsg("参数设置错误","WSNADDR的IP地址或者监听端口无效.");return false;}}else{m_Errno = -28;GetErrMsg("参数设置错误","WSNADDR的IP地址或者监听端口无效.");return false;}}}memset(m_CurWSNADDR,0,sizeof(m_CurWSNADDR));strncpy(m_CurWSNADDR,m_WSNAddrList[0],64);tuxputenv(m_CurWSNADDR);return true;}bool CTuxCall::TuxInit(){if(m_bInConnection){m_Errno = -9;GetErrMsg("初始化Tuxedo错误","Tuxedo远程连接已经建立,不需要再次建立."); return true;}TPINIT *tpinitbuf = (TPINIT*)tpalloc("TPINIT",NULL,sizeof(TPINIT));strcpy(tpinitbuf->usrname,m_UserName);strcpy(tpinitbuf->cltname,m_CtrName);int i=1;while (i<5){if (tpinit(tpinitbuf) == -1){m_Errno = tperrno;GetErrMsg("初始化Tuxedo错误","无法建立tuxedo远程连接.");memset(m_CurWSNADDR,0,sizeof(m_CurWSNADDR));strncpy(m_CurWSNADDR,m_WSNAddrList[i],64);tuxputenv(m_CurWSNADDR);i++;}elsem_bInConnection = true;break;}}tpfree((char*)tpinitbuf);return m_bInConnection;}bool CTuxCall::TuxTerm(){if( m_bInConnection && m_ConCount > m_ConnectionType){tpterm();m_ConCount =0;}else{return false;}m_bInConnection = false;return true;}bool CTuxCall::AllocDest(int size){m_RecBuff=tpalloc("CARRAY", NULL, size+1);if(m_RecBuff==NULL){m_Errno = tperrno;GetErrMsg("分配内存出错","可能是申请的空间太大,没有足够的内存可以使用."); return false;}return true;}bool CTuxCall::AllocSrc(int size){m_SendBuff=tpalloc("CARRAY", NULL, size+1);if(m_SendBuff==NULL){m_Errno = tperrno;GetErrMsg("分配内存出错","可能是申请的空间太大,系统内存不足!");return false;}return true;}int CTuxCall::SetSendBuf(char *szFormat,...){va_list ap;char *arg=NULL;int len = 0;va_start(ap,szFormat);char tmpStr[1024*10]={0};vsprintf(tmpStr,szFormat, ap);va_end(ap);len = strlen(tmpStr);if(m_SendBuff)tpfree(m_SendBuff);m_SendBuff=NULL;if (!AllocSrc(len+1)) return -1;memcpy(m_SendBuff,tmpStr,len);return len;}//直接使用该服务之前,必须保证m_SendBuff中的内容是正确的, //可以调用SetSendBuf()函数设置m_SendBuff的内容.bool CTuxCall::Invoke(char* SrvName,long InLen,long &OutLen) {if(m_RecBuff)tpfree(m_RecBuff);m_RecBuff=NULL;if (!AllocDest(1)) return false;if (!TuxInit()) return false;if(tpcall(SrvName,m_SendBuff,InLen,&m_RecBuff,&OutLen,0)==-1) {if(!m_bBeginTrans){tpterm();m_bInConnection = false;}char tmp[256];sprintf(tmp,"调用服务%s 出错",SrvName);m_Errno = tperrno;GetErrMsg("严重错误",tmp);return false;}if (m_ConnectionType>0) m_ConCount++;if(!m_bBeginTrans){TuxTerm();}return true;}bool CTuxCall::Invoke(char * SrvName,char * InStr,long InLen, char * &OutStr,long &OutLen, int flag){//首先清除Buffer,有效防止内存泄漏ClearBuffer();if (!AllocSrc(InLen)) return false;memcpy(m_SendBuff,InStr,InLen);if (!AllocDest(1)) return false;if (!TuxInit()) return false;if(tpcall(SrvName,m_SendBuff,InLen,&m_RecBuff,&OutLen,0)==-1){if(!m_bBeginTrans){tpterm();m_bInConnection = false;}char tmp[256];sprintf(tmp,"调用服务%s 出错",SrvName);m_Errno = tperrno;GetErrMsg("严重错误",tmp);return false;}if (m_ConnectionType>0) m_ConCount++;if(!m_bBeginTrans){TuxTerm();}OutStr=m_RecBuff;return true;}/*** 默认Invoke,默认服务名为TRANSMIT*/bool CTuxCall::Invoke(char * OpCode,...){va_list ap;va_start(ap, OpCode);//序列化输入参数va_end(ap);long nOutLen;char* pOutBuf;int nInLen = 0;char* pInBuf = NULL; //需要对输入的参数进行组合整理bool ret;{ret = Invoke(TRANSMITER,pInBuf,nInLen,pOutBuf,nOutLen); }catch(...){delete []pInBuf;return false;}delete []pInBuf;return ret;}/*** 指定服务名Invoke*/bool CTuxCall::Invoke(char* SrvName,char* OpCode,...){va_list ap;va_start(ap, OpCode);//序列化输入参数m_Col = 0;/*while ((arg =va_arg(ap,char*)) != 0){//至于如何把传入的参数组合成一个二进制字符串,//大家可以用自己的方法去处理,//这里涉及的是其他方面的技术,跟tuxedo无关,所以不跟帖. }*/va_end(ap);long nOutLen;char* pOutBuf;int nInLen = 0;char* pInBuf = NULL;bool ret = false;try{ret = Invoke(SrvName,pInBuf,nInLen,pOutBuf,nOutLen);}catch(...){delete []pInBuf;return false;}delete []pInBuf;return ret;bool CTuxCall::BeginTransaction(unsigned long timeout) {TuxInit();if(tpbegin(timeout,0)==-1){tpterm();m_bInConnection = false;m_Errno = tperrno;GetErrMsg("事务失败","无法开始事务");return false;}m_bBeginTrans = true;return true;}bool CTuxCall::Rollback(){if(!m_bBeginTrans){m_Errno = -101;GetErrMsg("事务失败","回滚之前应先开始一个事务!"); return false;}m_bBeginTrans = false;if(tpabort(0)==-1){tpterm();m_bInConnection = false;m_Errno = tperrno;GetErrMsg("回滚事务失败","调用tpabort()函数失败!"); return false;}TuxTerm();return true;}bool CTuxCall::Commit(){if(!m_bBeginTrans){m_Errno = -102;GetErrMsg("事务失败","提交之前应先开始一个事务!"); return false;}m_bBeginTrans = false;if(tpcommit(0)==-1){tpterm();m_bInConnection = false;m_Errno = tperrno;GetErrMsg("提交事务失败","调用tpcommit()失败!");return false;}TuxTerm();return true;}void CTuxCall::Disconnect(){tpterm();}void CTuxCall::ClearBuffer(){if(m_RecBuff)tpfree(m_RecBuff);if(m_SendBuff)tpfree(m_SendBuff);m_RecBuff=NULL;m_SendBuff=NULL;}void CTuxCall::SetClientInfo(char* username,char* ctlname){strncpy(m_UserName,username,64);m_UserName[63]="\0";strncpy(m_CtrName,ctlname,64);m_CtrName[63]="\0";}bool CTuxCall::SetConnectType(int contype){if (contype==0||contype==1||contype>=10){m_ConnectionType = contype;return false;}else{m_Errno = -34;GetErrMsg("参数设置错误","连接只能是0(长连接),1(短连接)和大于10的整数."); return false;}}bool CTuxCall::CheckWSNADDRValid(char* ipstr,char* port) {int iplen = strlen(ipstr);if (iplen > 15) return false;int count = 0;char ipstrSubs[4]={0};int iPos=0,i=0;while (i{if (ipstr[i]>="0"&&ipstr[i]<="9"){if (iPos>3) return false;ipstrSubs[iPos]=ipstr[i];iPos++;if (i==iplen-1){ipstrSubs[iPos]="\0";iPos = 0;}}else if (ipstr[i]=="."){if (iPos>3) return false;ipstrSubs[iPos]="\0";count++;iPos = 0;}else return false;if (iPos==0){if (atoi(ipstrSubs)<0||atoi(ipstrSubs)>255)return false;memset(ipstrSubs,"\0",4);}i++;}if (count!=3) return false;memset(m_CurWSNADDR,0,sizeof(m_CurWSNADDR)); strcpy(m_CurWSNADDR,"WSNADDR=//");strcat(m_CurWSNADDR,ipstr);strcat(m_CurWSNADDR,":");if (atoi(port)>1024){strcat(m_CurWSNADDR,port);}else return false;return true;}char* CTuxCall::GetErrorMessage(){return ErrMsg;}char* CTuxCall::GetCurWSNAddr(){return m_CurWSNADDR;}char * CTuxCall::GetResultData(){return m_RecBuff;}测试程序服务程序#include#include "transmit.h"#includeint tpsvrinit(int argc,char** argv){userlog("服务转发器transmitsrv启动成功.\r\n"); printf("服务转发器transmitsrv启动成功.\r\n"); return 0;}void tpsvrdone(){userlog("服务转发器transmitsrv关闭成功.\r\n"); printf("服务转发器transmitsrv关闭成功.\r\n"); }char* UpperCase(char* str){int i = 0;while(str!=0){str = toupper(str);i++;}return str;}char* LowerCase(char* str){int i = 0;while(str!=0){str = tolower(str);i++;}return str;}char * TrimStr(char * str,int size) {if(!str)return "";for(int i=size-1;i>=0;i--){if(str==" ")str=0;elsereturn str;}return str;}char* ltrim(char* str){if(str == NULL) return str;int len = strlen(str);for(int i=0; i{if(str != " "){memmove(str,&str,len-i);str[len-i] = 0;break;}else if(i == len-1){str[0] = 0;break;}}return str;}char* rtrim(char* str){if(str == NULL) return str;int len = strlen(str);for(int i=len-1; i>=0; i--){if(str!= " "){str[i+1] = 0;break;}}return str;}char *trimstr(char *str){rtrim(str);ltrim(str);return str;}///////////服务函数//////////////////////////////////////////////////////////////////====================== TRANSMIT 服务处理========================================//ProcessTRANSMIT函数负责解析客户端传递的参数,并决定该调用哪一个服务.#if defined(__STDC__) || defined(__cplusplus)void ProcessTRANSMIT(TPSVCINFO *rqst,long len,char* sname)#elsevoid ProcessTRANSMIT(*rqst,&len,*sname)TPSVCINFO *rqst;long len;char* sname;#endif{//服务.....}//TRANSMIT:服务转发器,客户端的程序统一调用TRANSMIT,然后由TRANSMIT服务//根据opcode调用相应的服务.#if defined(__STDC__) || defined(__cplusplus)void TRANSMIT(TPSVCINFO *rqst)#elsevoid TRANSMIT(*rqst)TPSVCINFO *rqst;#endif{char sname[32+10];long len=0;ProcessTRANSMIT(rqst,len,sname);tpforward(sname,rqst->data,rqst->len,0);tpreturn(TPSUCCESS,0,rqst->data,len,0);}//=====================TRANSMIT 服务处理结束=========================================//======================== 测试用的服务HelloWord ==================================#if defined(__STDC__) || defined(__cplusplus)void HelloWord(TPSVCINFO *rqst)#elsevoid HelloWord(*rqst)TPSVCINFO *rqst;#endif{//数据格式:操作码(16位)用户名(32)char opcode[17]={0};char username[33]={0};char* pBuf;int len;char retMsg[1024]={0};int retFlag = 0;printf("HelloWord: The Service HelloWord get request !\r\n");memset(opcode,0,sizeof(opcode));memset(username,0,sizeof(username));memset(retMsg,0,sizeof(retMsg));strncpy(opcode,rqst->data,16);strncpy(username,rqst->data+16,32);printf("HelloWord: [%s]\r\n",rqst->data);printf("HelloWord: opcode = %s, UserName= %s\r\n",trimstr(opcode),trimstr(username));if (!strcmp(opcode,"GetTime")){time_t timer;struct tm *tblock;/* gets time of day */timer = time(NULL);/* converts date/time to a structure */tblock = localtime(&timer);printf("Local time is: %s", asctime(tblock));sprintf(retMsg,"Now, Local time is: %s",asctime(tblock));retFlag = 1;}else if (!strcmp(opcode,"Hello")){printf("%s: First thanks. And welcome to use tuxedo .\r\n",username);sprintf(retMsg,"%s: First thanks. And welcome to use tuxedo .\r\n",username); retFlag = 1;}else{sprintf(retMsg,"[%s] %s",opcode,"无效的操作码!");}len = strlen(retMsg) + 1;pBuf = tpalloc("CARRAY",NULL,len);if(pBuf == 0){tpreturn(TPFAIL,0,0,0,0);}else{strcpy(pBuf,retMsg);if (retFlag==1){tpreturn(TPSUCCESS,0,pBuf,len,0);}else{tpreturn(TPFAIL,0,pBuf,len,0);}}}/////////////////// HelloWorld 结束/////////////////////////////////////客户端测试gTuxCall.SetClientInfo("zlwen","Test->GetTime");if (gTuxCall.SetWSNAddr("//192.168.1.7:44321")){ShowMessage(gTuxCall.GetCurWSNAddr());}else{ShowMessage(gTuxCall.GetErrorMessage());}int inLen = gTuxCall.SetSendBuf("%-32s%-16s","GetTime","TestName");//SetSendBuf的使用方法通printf().int outLen = 0;if (gTuxCall.Invoke("HelloWord",inLen,outLen)){ShowMessage(gTuxCall.GetResultData());}else{ShowMessage(gTuxCall.GetErrorMessage());}总结本程序在C++ Builder 5.0上通过测试.有什么问题欢迎通过邮件联系.。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

外部ws封装为tuxedo服务(outbound)步骤
一 服务配置 4、由.dep文件生成SALTCONFIG文件
wsloadcf -y <.dep文件>
外部ws封装为tuxedo服务(outbound)步骤
一 服务配置 5、由.mif文件,生成元数据注册文件。
通过如下命令来生成元数据注册文件(metadata repository)
mdr_datatypeapp.mif
封装tuxedo服务为ws(inbound)步骤(总)
一 服务配置 3、生成元数据注册文件(metadata repository)
通过如下命令来生成元数据注册文件(metadata repository)
tmloadrepos -i <.mif文件> <.repos文件>
封装tuxedo服务为ws(inbound)步骤(总)
一 服务配置 5、创建web service部署配置文件.dep。
<?xml version="1.0" encoding="UTF-8"?> <Deployment xmlns="/Tuxedo/SALTDEPLOY/2007"> <WSDF> <Import location="C:\dev2009\salttest\simpapp.wsdf"></Import> </WSDF> <WSGateway> <GWInstance id="GWWS1"> <Inbound> <Binding ref="simpapp:simpapp_Binding"> <Endpoint use="simpapp_GWWS1_HTTPPort"></Endpoint> </Binding> </Inbound> <Properties> <Property name="enableSOAPValidation" value="true"/> </Properties> </GWInstance> </WSGateway> <System></System> </Deployment>
一 服务配置 8、重新启动tuxedo 9、生成.wsdl文件。(要求tuxedo已启动) tmwsdlgen -c <.wsdf文件> -y -o <.wsdl文件>
有了这个文件,就可以给各种Web Service客户端做开发。
外部ws封装为tuxedo服务(outbound)步骤
一 服务配置 1、安装tuxedo和salt并配置环境变量 2、由.wsdl文件生成相关文件(包括.mif .fml32 .wsdf和.xsd 文件) 3、根据.wsdl和生成的.wsdf文件,创建.dep文件。 4、由.dep文件生成SALTCONFIG文件 5、由.mif文件,生成元数据注册文件。 6、修改.fml32文件中的base值,使fml32 field的ID唯一 7、配置环境变量,修改ubb文件,生成TUXCONFIG文件。 8、重新启动tuxedo。 二 服务调用开发 1、由.fml32生成.fml32.h文件 2、使用.fml32.h进行开发。
元数据注册文件要配置在ubb文件中。
封装tuxedo服务为ws(inbound)步骤(总)
一 服务配置 4、创建web service定义文件(.wsdf)。
<?xml version="1.0" encoding="UTF-8"?> <Definition xmlns="/Tuxedo/WSDF/2007" name="simpapp"> <WSBinding id="simpapp_Binding"> <Servicegroup id="simpapp_PortType"> <Service name="ToUpperWS"></Service> </Servicegroup> <SOAP style="document" use="literal"> <AccessingPoints> <Endpoint address="http://127.0.0.1:8080/simpapp" id="simpapp_GWWS1_HTTPPort"></Endpoint> </AccessingPoints> </SOAP> </WSBinding> </Definition>
封装tuxedo服务为ws(inbound)步骤(总)
一 服务配置 1、安装tuxedo和salt并配置环境变量 2、根据tuxedo服务创建服务配置文件.mif。 3、生成元数据注册文件(metadata repository) 4、创建web service定义文件(.wsdf)。 5、创建web service部署配置文件.dep。 6、根据.dep文件生成SALTCONFIG文件。 7、修改ubb文件,生成TUXCONFIG文件 8、重新启动tuxedo 9、生成.wsdl文件。 二 服务调用开发 1、根据.wsdl文件,做基本的ws开发。
tmloadrepos -i <.mif文件> <.repos文件>
元数据注册服务(outbound)步骤
一 服务配置 6、修改.fml32文件中的base值,使fml32 field的ID唯一
# FML32 Mapping File Generated by wsdlcvt *base -10000 <----- Please specify proper base number here. #name rel-number type #------------- --------add 1 fml32 addResponse 2 fml32 schema=ns:addResponse param0 3 long param1 4 long ws_return 5 long flags comment ------fullname=add, schema=ns:add fullname=addResponse, fullname=param0, schema=xs:int fullname=param1, schema=xs:int fullname=return, schema=xs:int
外部ws封装为tuxedo服务(outbound)步骤
一 服务配置 3、根据.wsdl和生成的.wsdf文件,创建.dep文件。
<?xml version="1.0" encoding="UTF-8"?> <saltdep:Deployment xmlns:saltdep="/Tuxedo/SALTDEPLOY/2007" xmlns="/Tuxedo/SALTDEPLOY/2007" xmlns:xsi="/2001/XMLSchema-instance"> <saltdep:WSDF> <saltdep:Import location="@APPDIR@/calc.wsdf"/> </saltdep:WSDF> <saltdep:WSGateway> <saltdep:GWInstance id="GWWS1"> <saltdep:Outbound> <saltdep:Binding ref="calc:CalculatorSOAP11Binding"> <saltdep:Endpoint use="CalculatorSOAP11port"/> </saltdep:Binding> </saltdep:Outbound> </saltdep:GWInstance> </saltdep:WSGateway> <saltdep:System/> </saltdep:Deployment>
Welcome to HUAWEI Technologies 使用SALT封装Tuxedo服务 presentation
2009年6月
内容提要
1. 封装tuxedo服务为ws(inbound) 2. 外部ws封装为tuxedo服务(outbound)
Tuxedo服务开发架构
Web Service Server
TMMETADATA SRVGRP=GROUP1 SRVID=2 CLOPT="-A -- -f <.repos文件>" GWWS SRVGRP=GROUP1 SRVID=3 CLOPT="-A -iGWWS1"
生成UBBCONFIG文件
tmloadcf -y <.ubb配置文件>
封装tuxedo服务为ws(inbound)步骤(总)
封装tuxedo服务为ws(inbound)步骤(总)
一 服务配置 2、根据tuxedo服务创建服务配置文件.mif。 service=ToUpperWS export=y servicetype=service inbuf=STRING outbuf=STRING tuxservice=TOUPPER param=name type=string access=inout size=1000
相关文档
最新文档