pb开发webservice的一点经验

sbks 2012-06-13 02:36:03
1.为什么要使用三层应用?
客户的应用要求在广域网上运行,数据库不在广域网上暴露,有两个途径实现:1.建议客户购买远程桌面管理软件,CS程序无需做任何更改,即可实现广域网应用;2.使用三层架构,客户端与中间服务器打交道,中间服务器与数据库打交道。
第一种方式,这个远程桌面管理软件也不算贵也不算便宜,关键是它大部分是卖站点数的,小型企业一般不愿意额外开支这部分费用。那么,就用PB自身来实现三层架构吧。

2.选webform,还是webservice?
webform的本质是把pb代码生成html代码,再发布到IIS服务器上。好处是:很容易转换;坏处是:想美化一下界面,需要更多的网页知识。我试玩了几下,放弃了这个。
webservice才是PB三层应用的核心。它的最大好处是:通过soap协议,将数据窗口对象进行传送。PB开发员需要做的只是转换一下开发思想,就可以使用纯PB script做出非常好的三层应用。

3.PB开发webservice的一些准备
(1)网络连接管理的问题:CS下,连接是不会断开的,有利于身份认证完成后就无需再关心这个事件。而BS时,连接是断开的。那么,身份认证的问题需要贯穿整个开发。
我的做法:登录后,确认身份成功,分配一个guid值做为令牌,当客户端需要做业务处理时,参数里都带着这个令牌,解决了连接的问题。
(2)数据连接管理的问题:CS下,数据库连接是不会中断的。而在BS时,网络连接是无状态的,所以,数据库连接也是断开的。
我的做法:在服务器端,每一个业务逻辑,都重新connect一次,逻辑完成后,disconnect掉。查过相关贴子,据说这样使用,IIS会自动管理数据库连接。因为没有相关工具的使用经验,无从查究。
(3)多表提交的问题:以往的CS程序下,多表提交是在客户端通过设置autocommit=false,手动来控制多表提交,如果有一个事情失败,就整个事务回滚。
我的做法:做一个多表提交的函数,一般是主子表结构,那么传入参数里就有两个blob,分别是主子表的dw语法,然后在服务端做多表提交控制
(4)数据存取效率问题:目前单机运行,还是很满意的。除了第一次使用时慢一点。以后如果有效率问题出现,先考虑使用压缩算法,把dw语法进行压缩,以减少对网络的依赖
(5)可以接受多少个客户端?这个问题目前未知。不过一般情况,我想三五百个客户端应该是没有太大压力的,如果客户端再多,可以建议客户购买更专业的可以放置pb对象的中间层服务器,比如sybase自己的easerver

4.如何开发第一个webservice
其实,用pb开发webservice是很简单的事情。第一个大前提就是:环境一定要做好。在安装pb时,会有提示说用到什么功能时需要什么样的环境。要开发webservice,就得安装.net framework sdk 2.0。要注意,是sdk,不是普通的那个。
其次,建一个webservice项目,然后建一些不可视的对象,将各种业务函数封装在这些对象里。网上所能找到的资料,已经足够你用来学习了。之所以资料不多,是因为它真的不复杂。建议去台湾的一个资讯网站去下载资料,我看好些资料是从它那里出来的http://www.mpinfo.com.tw/
照着这些资料,发布你的第一个webservice吧。
服务端的对象是,是不存在可视对象的,象窗口啦,数据窗口啦。数据窗口不在服务端,那么,如何使用数据窗口技术呢?不要忘了,数据窗口的不可视版本:datastore。在服务端的脚本里,定义一个datastore,然后与数据库连接,然后检索,然后使用getfullstate()得到blob,把blob对象通过soap传给客户端,客户端的dw.setfullstate()一下,哈哈,怎么样,看到通过webservice生成数据了吧。

5.客户端如何使用webservice
调用webservice时,PB是通过一个project来生成服务端对象的代理。这个代理的本质其实就是一些远程函数的定义。

6.常用的几个函数
不用说,首当其冲的就是getfullstate(),setfullstate()这一对宝贝函数。它是整个数据对象的语法包括数据,状态,都集中成一个blob中。
其次,dw.create()。这个函数也很有用。你可以从服务端取得dw object的syntax,然后在客户端接收这个syntax,再create()一下,哈哈,数据窗口就出现栏位了,而且是在客户端代码里没有dw object的前提下。

总结:pb的webservice大大地拓宽了pb的应用,而且非常的简单易用,希望更多的pb开发员加入到这个行列。不要以为其它的工具如何如何的先进,在快速应用方面,目前还是pb是首选。也不要以为这webservice有多复杂,我本身对这是很弱的,通过学习,一周之内,就把它理解并能应用了,想念聪明的你们更是得力。

我写这些的初衷,就是鼓励大家使用新技术,完成客户需求,这才是最重要的事情。

sybase继续加油,让pb的代码除了可以发布在iis,easerver,以后支持更多的中间件服务器,而且能跨平台,将是我们所有PB开发人员的福音
...全文
32755 127 打赏 收藏 转发到动态 举报
写回复
用AI写文章
127 条回复
切换为时间正序
请发表友善的回复…
发表回复
sbks 2014-11-03
  • 打赏
  • 举报
回复
引用 126 楼 laoer_2002 的回复:
网站的资料在那里下载?找不到
教材的下载见我在7楼的链接,我刚试了,下载链接仍然有效 我自己写的简单的代码,在我自己的资源里,应该还有 预祝WS玩得开心
laoer_2002 2014-10-13
  • 打赏
  • 举报
回复
网站的资料在那里下载?找不到
1055667097 2014-10-11
  • 打赏
  • 举报
回复
非常好,感谢上面关注的各位朋友
sbks 2014-09-23
  • 打赏
  • 举报
回复
引用 122 楼 yuyan5945 的回复:
看来还有人用PB,问个问题吧,不知是否能得到解决 用PB开发的WebService需要调用外部DLL,已经在项目的library files->win32 dynamic library files添加了DLL文件,但发布到WS上使用时还是用不了。哪位有这方面的经验可以分享一下?
我也是这么用 首先,检查一下网站目录下,是否存在该dll。dll发布后会被配置在xxx\bdlws\bin下 然后,有可能的情况是,有些32位的dll,在64位操作环境下会失效。 因此,建议你先找个简单的dll来调用,确认发布没问题;那余下的问题只能是该dll不能被iis托管使用的问题了,或许IIS有相关的设置需要去研究一下
sbks 2014-09-23
  • 打赏
  • 举报
回复
引用 120 楼 ansonboty 的回复:
还有一点,感觉上系服务器运行软件,刷新数据都系比较慢。但用CS模式就超快。前指点,谢谢
比CS是略慢,比如检索1000行数据,CS是瞬间,通过WS则大约1s,还算正常吧,多了blob,压缩,传递,解压缩这些步骤 建议你通过在服务端debug的方式,看哪句语句执行效率差,再进行改善
yuyan5945 2014-09-15
  • 打赏
  • 举报
回复
看来还有人用PB,问个问题吧,不知是否能得到解决 用PB开发的WebService需要调用外部DLL,已经在项目的library files->win32 dynamic library files添加了DLL文件,但发布到WS上使用时还是用不了。哪位有这方面的经验可以分享一下?
ansonboty 2014-09-13
  • 打赏
  • 举报
回复
还有一点,感觉上在服务器运行软件,刷新数据都是系比较慢,同用普通电脑作为客户端速度差不多。但用CS模式就超快。前指点,谢谢
ansonboty 2014-09-13
  • 打赏
  • 举报
回复
还有一点,感觉上系服务器运行软件,刷新数据都系比较慢。但用CS模式就超快。前指点,谢谢
ansonboty 2014-09-13
  • 打赏
  • 举报
回复
你好,请问你用pb webservice客户端的刷新速度如何。我现在服务器是放在啊里云,服务带宽5M。数据我已经压缩过了,大概10k左右,感觉刷新几行数据很慢。
sbks 2014-09-12
  • 打赏
  • 举报
回复
最近在同时对数十个数据库取数,可以认为是数据抽取吧.数据抽取的算法已经做成webservice,又做了一个定时器程序进行定时抽取.PB是单线程,按顺序抽取数据时,单库抽取如果时间在20s,那么20个库就需要400s,显得比较滞后.于是,研究了一个pb的多线程应用 pb的多线程应用相当的简洁,大致过程是: 1.定义一个不可视对象,做为线程的载体 2.在不可视对象里定义需要调用的函数.一些需要交互的数据,做成对象的变量 3.sharedobjectregister():注册线程,并将线程实例化 4.sharedobjectget():根据线程名字,获得实例 5.调用线程实例的自定义函数.要注意的是,需要使用post调用 6.等候线程执行完毕(判断的标志自行决定) 7.sharedobjectunregister():取消线程的注册 应用起来很惊喜,达到预期目标,一分钟内抽取完几十个数据库的数据毫无压力 下面是已经在用的代码片段.思路也是来自网络上各位pber对pb线程的介绍,只不过,作者们比较喜欢另外定义一个不可视对象来管理线程(这个对象被称为主线程),而我的主线程就是pb自身 个人感觉,pb对线程的管理,是通过线程名称来管理,不知道用线程数组是否也可以达到管理目标 还有一个注意事项:线程无法访问到全局变量,所以,需要交互的内容,需要定义成函数的参数给传给线程 //异步执行 ls_wssvr = profilestring(gs_appdir + '\init','业务数据库','地址','') //取得webservice服务地址,它被记在一个init文件中.本来我已经有一个全局变量来记录它的,但由于线程中无法对全局变量取值,只好用局部变量做参数传递进线程 .... thread = create nvo_soapthread //用来临时保存线程实例的对象 for i = 1 to ll_rc ls_md=dw_md.object.bm[i] ... k++ //因为之前还有一些判断的逻辑(未贴上),所以,要另外使用一个计数器来记录数组序号 ls_thread[k] = ls_md //用一个数组来保存线程名称,线程名称为ls_md的值 if sharedobjectregister('nvo_soapthread',ls_thread[k])<>Success! then messagebox('提示','共享对象失败') return end if sharedobjectget(ls_thread[k],thread) //根据线程名称,获得线程实例 thread.post of_get_ys(ls_wssvr,ls_rq) //异步调用,实现多线程管理. next //取得回执 ll_rc = k for i = 1 to ll_rc sharedobjectget(ls_thread[i],thread) //根据线程名称,获得线程实例 do while thread.of_get_rn()='' //of_get_rn的返回值做为线程执行完毕的标记 yield() //yield函数扮演非常重要的角色.意思是说,线程还没执行完毕,把队列里的消息另外处理一下,但控制权还在这个代码片段里 loop mle_1.trigger event ue_write(thread.of_get_rn()) //显示结果到一个mle_1的控件里,ue_write是mle_1的自定义事件,用来实现换行与滚屏 sharedobjectunregister(ls_thread[k]) //根据线程名称,解除注册 next if isvalid(thread) then destroy thread
sbks 2014-08-12
  • 打赏
  • 举报
回复
[转贴][转贴][转贴][转贴][转贴][转贴][转贴] ---------------- pb12 开发 webservice 注意事项 分类: powerbuilder 2011-01-04 10:02 2004人阅读 评论(0) 收藏 举报 webserviceasp.netiissybaseoracle10g.net系统环境:winxp sp2 + oracle10g + iis5.1 1. 检查本机 iis 是否正常,若 iis 不能运行或浏览默认网页时报权限类错误,检查“本地用户和组”中 3 个相关的内置账号是否启用(启动 iis, asp.net, internet 来宾)。 2. pb 开发 ws,必须安装 framework3.5 sp1 和 framework sdk2.0,为简单起见,直接安装 vs2008,之后再打 vs2008 sp1 补丁,微软官网的那个补丁包需要用较新版本的 iso 工具才能正常读出。 3. 由于 .net 语法更为严格,有符号和无符号的同类型数值变量不能做互相赋值或比较等操作,例如:int 和 uint;此问题可能会导致发布时 pb 直接崩溃! 4. 无符号数值类型不能用于递减循环,例如:for uint = 100 to 1 step -1;发布时通常会给出编译警告,但有时却会导致 pb 异常关闭! 5. 全局函数不能使用 this 代词,可用 GetApplication() 替代。 6. 在 c/s 应用中调用 ws,需要把 ../share/powerbuilder 中的 pbsoapclient120.pbd(java 标准)或 pbwsclient120.pbd(.net 标准)文件加入到 target 的库列表中;它们分别对应 EasySOAP 和 .Net 引擎。 7. 使用 .net target 做客户端应用的话,必须把 pbwsclient120.pbx 导入到自已的 pbl 中;如果导入报错的话,可以从 pb 自带的 ws 例程中导出相关的 3 个对象为 *.sr* 文件,再导入自己的 pbl 里。 8. 如果调用 ws 时 CreateInstance() 出现 runtime 错误,则可能是由于老版本 pb 在 system32 目录下放有与 pb 共享目录下同名的老版本 dll,删除或用新版本 dll 覆盖即可(如 libeay32.dll)。 9. 发布 ws 的详细日志文件可以在本工程下的 pb2cstempout 目录中找到。 10. FileOpen() 必须用流模式,所以 FileWriteEx() 也必须用 blob 类型。 11. (尚待进一步研究)不能直接读写 iis 虚拟目录以外的文件,必须把其添加到 iis 的虚拟目录中;同时要保证该文件所在目录及上层目录 asp.net 拥有相应的访问权限;虚拟目录的真实路径可用 MapVirtualPath() 取得,但不能用真实路径访问虚拟目录的文件,也不能以相对路径访问应用的上层目录及文件(仅可访问 /app_root/file/session/__webservice__/c 中会话产生的临时目录及文件)。 12. 发布给外界调用的 ws 函数不允许重载(这的确是个很糟糕的限制)。 13. 应用对象不能声明实例变量,全局变量只对当前会话有效;应用对象的脚本不会执行;以 post 方式调用的函数不会执行。 14. 创建对象时所用的模板类型必须和声明的一致,不能降级构造;例如:继承自 transaction 的自定义对象 n_tran_base,声明为 n_tran_base itran_obj,则实例化时不可以写成 itran_obj = create transaction(赋值、比较操作同理)。 15. 数据库驱动目录须要设置 asp.net 的访问权限(重启),如 c:/oracle/product/10.1.0/client_1。 16. 要使用 sybase datawindow ps 打印机,需要在打印机的安全设置里添加上 asp.net, internet 来宾, network service, 启动 iis 四个账号为允许打印(第一次打印时必须设置,之后可以删除),方可确保 PrintDatawindow(), Print(), SaveAs() 这些函数能正常生成 pdf 文件(但 db ole 控件的内容不能显示)。 17. 可以通过 inet 和 internetresult 两对象的配合,获得 /app_root/print/session/__webservice__ 打印目录下的文件列表,并分析出打印后的正确文件名;同理,亦可用此方法获得 pdf 文件的内容。 18. (尚待进一步研究)Run() 函数已失效,可用 API 替代,如 CreateProcess() 启动服务端的 exe 文件,但受限于 iis 的权限控制,只能在任务管理器中看到此进程,并不能正常运行(即便是无界面的 exe 也是如此)。 19. (尚待进一步研究)据 sybase 新闻组的说法,ole 对象在 .net 应用中无法使用,这并不是 pb 的限制,而是微软自身的问题。所以 db ole 控件也失效了,如果仍想在客户端使用的话,可在检索含有 db ole 的数据窗口时转交给 c/s 程序执行,然后再传回 ws。 20. 关于进程间通讯,DDE 仅能建立管道,但无法执行链接;Send() 函数已失效,只有通过 API SendMessage() 向服务端进程发送消息(ws 没有窗口句柄,不能收到消息),本应使用 WM_COPYDATA 通过共享内存来传递数据(在 other 中拦截 message.number=74),但服务端进程收到的却是错误数据;既然只能传递消息本身,倒不如用 pbm_custom01(1024) 更加简单。 21. 若数据库驱动不能使用 iis 连接池的话,则必须在 ws 执行完成后,由代码主动断开连接;但由于 ws 的析构事件不会在退出时立即执行,所以必须在每个接口函数返回前断开连接;而且,为防止函数中忘记断开或异常退出,析构事件仍需写上 disconnect;。
WellSoft 2014-08-03
  • 打赏
  • 举报
回复
引用 115 楼 WellSoft 的回复:
[quote=引用 114 楼 sbks 的回复:] [quote=引用 112 楼 WellSoft 的回复:] webservice如何直连SQL2008?
既然都是微软的产品,那么,服务器操作系统一定是已经支持old db驱动的,在连接数据库时,就象cs环境下,直接设置sqlca就可以了,也没必要使用odbc. odbc用来没有直连驱动时才会采用的连接方式 webservice端的数据操作,跟cs下没有太大的差异,仅仅是没有datawindow 控件用了,只能用datastore,而通过getfullstate()与setfullstate()进行传递[/quote] 用直连方式直接设置sqlca,一开始是连接不成功,也没开过代码,不知怎么的现在就可以了,莫名其妙的问题。[/quote] 也没改过代码
WellSoft 2014-08-03
  • 打赏
  • 举报
回复
引用 114 楼 sbks 的回复:
[quote=引用 112 楼 WellSoft 的回复:] webservice如何直连SQL2008?
既然都是微软的产品,那么,服务器操作系统一定是已经支持old db驱动的,在连接数据库时,就象cs环境下,直接设置sqlca就可以了,也没必要使用odbc. odbc用来没有直连驱动时才会采用的连接方式 webservice端的数据操作,跟cs下没有太大的差异,仅仅是没有datawindow 控件用了,只能用datastore,而通过getfullstate()与setfullstate()进行传递[/quote] 用直连方式直接设置sqlca,一开始是连接不成功,也没开过代码,不知怎么的现在就可以了,莫名其妙的问题。
sbks 2014-08-02
  • 打赏
  • 举报
回复
引用 112 楼 WellSoft 的回复:
webservice如何直连SQL2008?
既然都是微软的产品,那么,服务器操作系统一定是已经支持old db驱动的,在连接数据库时,就象cs环境下,直接设置sqlca就可以了,也没必要使用odbc. odbc用来没有直连驱动时才会采用的连接方式 webservice端的数据操作,跟cs下没有太大的差异,仅仅是没有datawindow 控件用了,只能用datastore,而通过getfullstate()与setfullstate()进行传递
WellSoft 2014-07-28
  • 打赏
  • 举报
回复
webservice如何直连SQL2008?
WellSoft 2014-07-28
  • 打赏
  • 举报
回复
webservice连接数据库必须是ODBC吗?
lao_bulls 2014-07-28
  • 打赏
  • 举报
回复
多谢楼主,mark!
Allan_xd 2014-07-13
  • 打赏
  • 举报
回复
这帖这么火,有没有好心人帮我一把啊,我的问题见帖子:http://bbs.csdn.net/topics/390832226
sbks 2014-07-12
  • 打赏
  • 举报
回复
前些天发生了这样的异常 客户端代码编译时,什么提示都不出现,pb直接异常关闭.再打开这具target时,提示需要megrate,而进行megrate时,又是无提示直接异常 通过把pbl挂到其它的target上反复regenerate,然后再编译,最后把问题的根据定位在两个窗口上.可是奇怪的是,这两个窗口的代码找不出有错误的地方,把代码屏蔽后,可以正常编码,但是一旦把屏蔽去掉,马上又不行 想来想去,可能是pbl这个文件本身对对象的管理也许有差错了.再次修复了这两个窗口,然后新建一个pbl,把出问题的pbl里的对象一个一个地移到新的pbl里,最后,删除旧的pbl,把新的pbl改名成旧的pbl,再次打开时,终下完美解决了 结论是:pbl自身带有对象管理的内容.如果莫名奇妙的无法编码时,可以考虑把对象移到新的pbl文件中 很久很久以前,曾遇上同样的问题,也花了很长时间找到解决方案,但忘记了.于是在这里记录下来,希望以后还能想得起来
laoer_2002 2014-06-14
  • 打赏
  • 举报
回复
谢谢楼主分享
加载更多回复(99)

662

社区成员

发帖
与我相关
我的任务
社区描述
PowerBuilder Web 应用
社区管理员
  • Web 应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧