Welcome

首页 / 软件开发 / VFP / 用Web Service传送文件(二)

用Web Service传送文件(二)2007-05-08更多话题

今天是 2002年7月20日。一个星期前,我推出了本文,得到了一些朋友的相应。他们提出了一些问题,我希望通过续写此文一并作答。

实现文件上传

朋友们问我,你的示例代码里只有文件从服务器下载到客户端的介绍,是不是在暗示 Web Service 不能实现文件从客户机上传到服务器?不是,这是我的疏忽,本来应该提到 “文件上传” 的问题!

其实这里所谓 “文件上传” 是很简单的,只不过是 “文件下载” 的逆向思维!客户端把文件读起,并转换成为 Base64 编码的 XML 字符串,作为调用服务器有关接口函数的参数;服务器只要把客户端送过来的XML字符串解码保存成为文件即可!

服务器端代码

FUNCTION SaveFile(sUser as String,sPassWord as String,sFileName as String,sXml as String) as Boolean
IF sUser<>"Admin" OR sPassWord<>"PassWord" then
RETURN .f.
ENDIF

IF STRTOFILE(STRCONV(sXml,14),DataBasePath+sFileName)>0 then
RETURN .t.
ELSE
RETURN .f.
ENDIF
ENDFUNC

这里的核心代码就是:STRTOFILE(STRCONV(sXml,14),DataBasePath+sFileName) 。它的作用就是:对参数 sXml 进行 Base64 解码,并把解码后的数据保存为文件。

另外,一些网友提到了是不是用户验证的问题,这里我用了最简化的代码解释一下:

IF sUser<>"Admin" OR sPassWord<>"PassWord" then
RETURN .f.
ENDIF

这里要求用户名(sUser)为“Admin”,口令(sPassWord)为"PassWord" 时,才可以使用本接口函数。不然函数直接返回,而不往下面继续执行!

大家想象一下,这段简单的代码其实可以扩充成为复杂的 “用户、权限” 系统,这只是普通的程序设计概念,这里就不多说了!

客户端的代码

完整代码,详见 SaveFile.prg

#define TempPath "J:websClientData"
LOCAL mywebs as FoxWebService
LOCAL loWS
loWS = NEWOBJECT("Wsclient",HOME()+"ffc\_webservices.vcx")
loWS.cWSName = "FoxWebService"
mywebs = loWS.SetupClient("http://BOEWORKS/FoxWebS/FoxWebService.WSDL", "FoxWebService", "FoxWebServiceSoapPort")
IF mywebs.SaveFile("Admin","PassWord","pic.jpg",STRCONV(FILETOSTR(TempPath+"yl_22_28.JPG"),13))
MESSAGEBOX("成功!")
ELSE
MESSAGEBOX("失败!")
ENDIF

客户端的代码更是简单,核心就是:mywebs.SaveFile("Admin","PassWord","pic.jpg",STRCONV(FILETOSTR(TempPath+"yl_22_28.JPG"),13))。其作用是读取 JPG 文件 yl_22_28.jpg,并对它进行 Base64 编码,最后作为 SaveFile 接口函数的 sXml 参数送往服务器!

就这个应用来说,我的想法是把2002年7月22日到7月28日的“日历”替换原先的日历文件!

Web Service 传送文件与 FTP 的简单比较

Web Service 采用的 Http 协议的 “客户端请求、服务器端响应” 的模式,属于同步机制!也就是说客户端调用服务器接口函数以后,就等待,直到服务器给出结果(或者超时)!这种模式的好处在于:客户机、服务器交互时就像我们在Visual FoxPro 里调用内部函数那样—等待返回结果,这给编程带来了极大地方便!个人感受,用 FTP 控件,交互性没有 Web Service 好!

大家注意一下,我们用 Visual FoxPro 编写 Web Service 时,可以编写很多逻辑代码。换言之,用 Web Service 传送文件时,服务器更客户化,无论是上传、下载文件,我们的服务器都可以完成复杂的客户化的逻辑代码!当然,如果你有兴趣编写 FTP Server 的话,一样可以做到!

说着这么多,归根到底一句话:Web Service 不是为了传送文件而设计的,FTP 天生就是传文件的!可能有人要揍我了,我们辛苦看了2个星期的文章,换回的是一句:Web Service 不是为了传送文件而设计的。

这一点大家一定要注意:Web Service 传文件是此技术的一项副产品,而不是设计时的出发点!Web Service的函数调用模式,特别适合商业逻辑的实现。FTP 是文件传输协议,被广泛使用,自然有它的优势,例如两进制文件直接传递、断点续传等!

所以,我们在平时应用中,如果文件体积不大,并且传送文件的需求集合在 Web Service 应用里的,就应该使用这里我们介绍的方法:用 Web Service 传送文件!如果只是一个孤立文件传送任务或者被传送的文件很大,就应该采用 FTP 或者是 Email 方式!

所谓文件的大小不是一个定数。我个人的意见是关键看传送的时间,如果一个1M的文件,要传送10分钟,我想对这种环境来讲 1M 就是一个大文件了;反过来,如果一个 5M 的文件,只要用 30 秒就能传递完成了,那么在这种环境下它只是一个小文件!

进一步,这个等待时间的长短,是要您自己决定了!

异步调用 Web Service

这里就有人问道:我的Web Service提供的接口函数工作时间比较长,能不能实现客户端调用以后,不等待返回结果而继续处理其他任务!

这显然是希望得到一种 “异步处理” 的环境!刚才我已经提到了 Web Service 是以“同步模式”工作的,更明确的说法是:没有异步工作的 Web Service,只有对 Web Service 的异步调用!显然,问题的关键在客户端了!

在 Visual FoxPro 如何实现对 Web Service 的异步调用,我现在还没有头绪!不过在 .net 里倒是可以实现,有两种方法:回调函数和WaitHandle() 函数。前者适合 WinForm,后者适合于 Asp.Net。

Microsoft Soap Toolkit 3

前一些天,MS 推出了 Soap Toolkit 3,在这个版本里,MS 对文件传递有了专门的支持。有兴趣的话,您可以研究一下:http://msdn.microsoft.com/downloads/default.asp?URL=/downloads/sample.asp?url=/MSDN-FILES/027/001/948/msdncompositedoc.xml

Visual FoxPro 7 默认使用 Soap Toolkit 2,本文的代码能在 Soap Toolkit 2 以上版本中运行!