PB教程第十七章.doc_第1页
PB教程第十七章.doc_第2页
PB教程第十七章.doc_第3页
PB教程第十七章.doc_第4页
PB教程第十七章.doc_第5页
已阅读5页,还剩7页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

171 创建分布式程序上几章中,我们介绍了PowerBuilder分布式计算的基本概念,在接下来的章节中,我们将做一个简单的分布式程序。我们来看一下一个已经存在的应用程序,然后将做成的分布式运行的程序。单击Library按钮,打开一个名为Clients的库,单击Clients应用对象。按Run按钮(图17-1)。这里没有提供现成的数据库,读者需要自行建立。图17-1这是一个商品预定程序,所预定的是个人电脑配件。这是一些电脑常用配件名,旁边所列的配件的价格,这些价格来自电脑分销商的远程数据库。分销商将定期更改这些数据库中的价格表。最后的分销商给购买者折扣。与电脑配件不同的是,折扣值的是不公开的,分销商将给予不同的购买用户以不同的折扣,折扣的计算方法是秘密的,并且不断变化。因此,我们想把电脑预定程序做成一个分布式运行的程序,让计算折扣的程序运行在我们的服务器中,这样做的目的一方面是保密,另一方面,在分销商更改折扣算法时,只需更服务端程序,而不用更改在客户端中的电脑预定程序。172 Nonvisual Object 与 Proxy Object第一步,我们所做的是将折扣计算模块生成一个非可视对象NVO。单击用户对象按钮(user object),按NEW,然后选择Class框中的Custom按钮,系统出现一个用户对象窗口。我们可以注意到窗口的标题栏中有一句话为:Inherited from Nonvisual Object,它说明我们所创建的对象正是NVO。接着我们为NVO定义一个函数。打开Declare菜单中User Object Functions,按NEW按钮,这样就打开了函数定义窗口(图17-2)。这个函数名为GetDiscount,它需要有一个参数为CustomName(用户名),类型为STRING(字符串),返回值为DECIMAL(小数)。图17-2这就是我们的折扣函数。假若用户名为Mohair,则我们给予九折,否则,给九五折。实际函数可能不会这么简单,这里只是一个例子。if upper(CustomName)=MOHAI then return 0.90else return 0.95 END IF关闭函数定义窗口,存盘。把这个NVO对象取名为Cnvo_discount。图1回顾一下我们以前说过的分布式示意图,如图1。下面我们来生成非可视对象Cnvo_discount的代理对象。在用户对象画板上按右键,选中弹出式菜单的set proxy name,取名为Cpo_discount(图17-3)。在File菜单中选择Save,这样就生成了一个为名为Cpo_discount的代理对象。我们可以在Library画板检查一下,PowerBuilder是否真地生成了这个对象。注意,我们是在File菜单中选择Save后生成了这个对象的,如果不将之保存,那么,我们只是为这个NVO设置了一个属性,并未生成代理对象。现在,我们已有了两类对象,一个是非可视对象Cnvo_discount,它是折扣计算程序的真正实现的地方,一个完整的对象。另一个是名为Cpo_discount的代理对象,它定义了前者的接口。我们试用鼠标的右键,来编辑这个对象,可以发现,系统并不允许进行编辑,因为它并不是一真实的对象。图17-3173 创建 Connection Object现在,我们已经定义了NVO,并生成它的代理对象,下一步再来看一看如何定义和初始化它一个链接对象Connection Object。与Transaction对象不一样,系统并不为应用程序自动生成这个对象,而需要自已手工定义。打开应用程序画板,选择它的Open事件。在其中只有一句打开窗口语句:Open (Win_shoping)。我们定义一个全局变量,输入:Connection myconnect。再从脚本编辑器中输入myconnect = create connection,为这个connection对象进行初始化。接着我们赋予它三个最基本的属性值:application、driver和location.。在不清楚之前,我们先给它们空值。至此为止,已经为connection对象初始完毕,我们还需用它来服务器建立联系。输入myconnect.ConnectToServer()。为了检查它是否真地找到了服务器,我们还需要输入一些脚本来验证它的返回值。如它的返回值不为空,则程序提示一些出错信息。如果等于0,则说明它已经正确链接到服务器,于是进一步打开主窗口win_shoping(图17-4)。myconnect = create connectionmyconnect.Application = myconnect.Driver = myconnect.Location = myconnect.ConnectToServer()if myconnect.ErrCode 0 then Messagebox(Server Error,Cannot Connect to Server) else open(win_shoping)end if我们建立了myconnect对象,相应地,还应该在程序结束之前将它释放掉,以便系统回收这个对象所占的内存空间。打开Close事件,先中止服务端的服务线程,同时释放服务器为我们分配的内存空间。输入myconnect.DisconnectServer()。随后,再释放myconnect对象,输入destroy myconnect。在PowerBuilder中,如果创建一个用户自定义的对象,我们就在不需要时把它释放掉,如图2所示。myconnect.DisconnectServer()destroy myconnect图17-4图 2接下去,我们把这个代理对象加到应用程序中。打开窗口win_shoping,在“折扣”按钮中加入代码。Cpo_discount po_discount:定义一个NVO对象实例;po_discount = create Cpo_discount:初始化这个NVO实例;po_discount.SetConnect(myconnect):这一句,我们为代理指定链接对象;这样每当代理对象调用了一函数,myconnect对象就为应用程序重定向到远程的NVO中,这个NVO存在于服务器中。最后,我们释放这个实例。如图3。图 3现在,我们已经把程序改成了一个在分布式环境下运行的应用程序。在客户端中,所有函数都指向了这个po_discount代理对象。在测试这个程序之前,我们对myconnect对象属性作一些修改。再打开Application画板,我们把myconnect的driver属性改为local,并让其它两个属性继续为空。当driver的值为local,PowerBuilder就会把分布式程序当作非分布式程序来运行。当程序调用代理对象,代理转向Connection对象,如果Connection对象发现driver为local,Connection就不会发链接请求信息。我们来测试一下这个程序。按下运行按钮,程序被正确运行了。单击“Discount”,程序返回了“0.90”。如图 4 。图 4174 把 NVO 移到Server中至此为止,这只是一个单机程序,还没有分布式运行。接一去我们将要NVO移到另外一个PB库中,形成服务端运行的程序。单击New按钮,系统弹出一个对话框,输入一个新的库名Server,再为Server生成一个新的应用名,名字也为Server,我们不需要系统自动生成的框架。接着,我们想把Clients库中的Cnvo_discount移至Server库中。打开Library画板,单击Clients点PBL,选择NVO对象Cnvo_discount,单击右键,选择Move。再查看Server库,可以发现在Server库中,原来在Clients中的Cnvo_discount已经移到了Server中(图17-5)。图17-5下一步,与客户端程序相类似,我们为服务端程序定义、初始化Transport对象。单击Server Application,打开脚本,打开Declare中的全程变量定义框。输入transport mytrans,创立一个名为mytrans的transport对象,关闭全程变量定义框。在脚本编辑器中,mytrans = create transport,初始化这个对象。然后,与Connection对象一样,我们还需要mytrans对象设置两个基本属性:应用名Application,驱动程序名Driver。我们暂时把它们设为空(图17-6)。mytrans = create transportmytrans.Application = mytrans.Driver = 图17-6随后,找开应用对象的Close事件,输入destroy mytrans,以便系统回收mytrans对象分配的资源。关闭脚本编辑器。175 创建Server 界面至此,我们已经创建了Server库,把Clients库中NVO对象移至Server库中,定义并初始化了Transport对象,接下去需要定义一个运行Server的界面。在钮按栏中按下窗口画板按钮,选择新建。我们将把这个窗口作为运行Server的主窗口,首先在窗口中移入两个按钮,一个,用来启动服务器的服务进程,取名为“Start”,另一个按钮用来中止服务进程,取名为“Shutdown”。为了程序更加可视一些,我们再定义一个画面,用来标志服务是否正常启动。移入一个Picture控件,点取右键,选择编辑属性命令Property,系统弹出对象属性对话框。在File Name中点取Browse,选入RED.BMP(自行使用画图工具制作一个全红的图片即可),OK。当这个画面中的绿灯亮起来时,就认为服务器已经正确启动了,如果画面中是红灯时,则服务被中止了。GREEN.BMP是一张全绿的图片,也需要自行制作。调整一下窗口中控件的位置,然后定义这个窗口的属性。我们把这个窗口名定义为“Discount Computing Server”。接下去,我们来为这两个按钮加上一些适当的脚本,让服务端程序正确运行起来。打开Start按钮的Clicked事件。在Start按扭被按下时,我们应该让Transport对象侦听来自客户机中Connection对象的消息。输入脚本mytrans.listen()。为了检测是否真地收到了一个正确的Connection对象,我们还需要检查一下对象的返回值。如果返回值不等0,则说明程序得到了一个错误的返回值,服务器没有正确地启动,需要提示一些出错信息。如果不是,则加载显示绿灯的图片,表明已经正确启动。(这个检查由读者自行思考,此处直接显示绿色)mytrans.listen()p_1.picturename=green.bmp当Shutdown被按下时,我们需要Stop Listening,关掉服务进程。同样,还需要把所显示的图片更改为“红灯亮”。mytrans.stoplistening()p_1.picturename=red.bmp保存所写的脚本,离开窗口画板,保存窗口,把它取名为win_server。继续回到应用对象,再看一下应用对象的脚本。打开脚本编辑器,选择Open事件。我们在这里初始化了一个名为mytrans的tranport对象,并为它设置了一些基本属性。接下去,为在两台机器上来测试这两个程序作一些准备工作。打开Application画板,选取Server应用对象,再打开Open事件所对应的代码。在上几节中,定义了一个Tranport对象,但是并未给它赋值。现在,我们将给予它一些适当的属性值。Driver指的是应用程序进行网络通信所用的网络协议。它可以为NamedPipes、或者是WinSock。在Win95或NT中,我们一般选择WinSock,它所对应用低层网络协议为TCP/IP。Application指的是服务器应用名,TCP/IP中,它对应的是一个服务进程的端口号,是一个整型的数值。如,Telnet服务端口号为23,FTP服务端口号为21。为了不与系统服务进程发生冲突,我们可以选择大于4096的任何一个数值。在这里,我们先将它设为5555,然后保存所作的修改。mytrans = create transportmytrans.Application = 5555mytrans.Driver = WinSock程序员在编写一些网络环境下的程序时,往往首先在单机的环境下来测试程序。我们将在同一台机器中同时运行Clients和Server。在成功生成EXE后,关闭项目对话框,给它取名为Server。图17-7现在转到资源管理器中,来查看一下Server.EXE。找到了它之后,双击,启动服务端程序。在你运行EXE的时候,可能会遇到一些错误提示,系统告诉你找不到一些必要的DLL文件,有三个方法来解决这个问题,可以把位于Common Files目录下的Powersoft Shared目录中的所有以DLL结尾的文件都复制到生成EXE文件所在目录;你可以在找到在PowerBuilder系统目录下一个名为PATHGEN的文件,为EXE文件设置路径;第三个方法是为你的应用程序做安装程序。改变环境变量是最方便的做法:我的电脑属性高级环境变量PATH。接下来,我们来修改客户应用程序,让它可以和Server链接。打开Library窗口,选择Clients库,双击Clients。重新回到应用对象的Open事件中,看看那里所写的脚本。在这里,程序初始化了Connection对象,我们还需要给它的三个属性赋于适当的值,让它可以与Server会话。我们把Application属性设为“5555”,这是一个TCP/IP的端口号,它必须与我们在服务端程序所设的端号一致,以便客户端程序能找到在服务器中运行的服务进程。把Driver属性设为“WinSock”,说明应用将用TCP/IP协议进行通信。最后把服务端程序Location设为LocalHost(本机),当客户应用程序发现Location为LocalHost,它就在本机里寻找服务端程序,而不是在网络中。myconnect = create connectionmyconnect.Application = 5555myconnect.Driver = WinSockmyconnect.Location = LocalHostmyconnect.ConnectToServer()if myconnect.ErrCode 0 then Messagebox(Server Error,Cannot Connect to Server) else open(win_shoping)end if关闭脚本编辑器,选择保存(图17-8)。图17-8我们测试一下这个程序,按下“Discount”,程序正确返回了“0.9”。如图17-9。再来看一看如果关闭服务会发生什么事情。在Server中按下“ShutDown”,再击“Discount”,Clients程序返回错误信息。如图17-10。图17-9图17-10至此为止,我们已经看到分布式PowerBuilder在单机环境的运行

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论