半岛权威十大直营(官方)网站

RealThinClient SDK Pro教程:从服务器发送大文件(第5课)

翻译|使用教程|编辑:况鱼杰|2019-07-30 16:53:09.013|阅读 193 次

概述:本教程将会介绍创建一个能够发送文件的Web服务器,无论其大小如何。在此过程中,我们必须小心服务器的内存,服务器内中可能有一个非常大的文件,不需要因为这个文件把所有的内存都占用了。

# 界面/图表报表/文档/IDE等千款热门软控件火热销售中 >>

相关链接:

    RealThinClient SDK是用于开发标准的HTTP(S)服务器,ISAPI扩展以及客户端的VCL控件。可用于Windows下的CodeGear Delphi 6-2010。关于RealThinClient SDK的教程会持续更新,本节是RealThinClient SDK的第四课,如何从服务器发送小文件。

点击下载最新版RealThinClient SDK


    本教程将会介绍创建一个能够发送文件的Web服务器,无论其大小如何。在此过程中,我们必须小心服务器的内存,服务器内中可能有一个非常大的文件,不需要因为这个文件把所有的内存都占用了。

    在前两个示例中,我们一直在RtcDataProvider组件的OnCheckRequest和OnDataReceived事件上发送所有内容。现在,为了能够发送大内容(大文件),除了我们从RtcDataProvider组件使用的事件之外,我们还需要OnDataSent事件。在先前调用Write函数准备的所有数据都已发送到客户端并且所有发送缓冲区都为空之后,将调用此事件。另外,我们需要对TRtcDataServer的Response属性进行一些检查。 

    我们将使用第4课(感兴趣的用户也可以查看一下)开发的代码作为基础,就能够从我们的服务器发送大文件。我们为每个单个事件调用定义了16K的内存限制,以便为从我们的服务器请求文件的任何客户端保持服务器的内存使用率低至16K。  

    接下来看看具体的步骤:

  1. 打开我们的第4课代码

    项目开放

  2. 更改我们的RtcDataProvider的OnCheckRequest事件。 

        我们将更改最后一个RtcDataProvider组件的OnCheckRequest事件,将Response.ContentLength值设置为文件大小。为此,请双击最后一个RtcDataProvider组件以跳转到OnCheckRequest事件。事件只有一小部分,但为了将它们保存在一个地方,这里是完整的新事件实现的代码:

  3. procedure TForm1.rdpFilesCheckRequest(Sender: TRtcConnection);
    var
    vsFileName : string;
    begin
    with TRtcDataServer(Sender) do
    begin
    vsFileName := GetFullFileName(Request.FileName); //(1)
    Accept;
    Request.Info['FName'] := vsFileName;
    Response.ContentLength:=File_Size(vsFileName);//(2)
    WriteHeader;//(3)
    end;
    end;

    我们在做什么?

    • 正如在演示3中所做的那样,将文件名存储在请求中,这样不必在以后再次重新创建它。

    • 需要设置Response.ContentLength,告诉RtcDataServer我们响应中的内容(数据)有多大。如果不设置Response.ContentLength,RtcDataServer将假定调用Write的第一个事件来响应,并将计算ContentLength。

    • 发送响应标头,这样就不必在文件大小为零的情况下调用Write。

  4. 更改我们的RtcDataProvider的OnDataReceived事件。

        现在,我们将更新OnDataReceived我们的事件RtcDataProvider,为了只发送有限的数据量(我们设定该限制到16KB)。

  5. procedure TForm1.rdpFilesDataReceived(Sender: TRtcConnection);
      var
        vsFileName  : string;
        viSent      : integer;
    begin
      with TRtcDataServer(Sender) do
        if Request.Complete then
        begin
          if Response.ContentLength > Response.ContentOut then //(1)
          begin
            vsFileName := Request.Info['FName'];
     
            if File_Exists(vsFileName) then
            begin
              if File_Size(vsFileName) = Response.ContentLength then //(2)
              begin
                viSent := Response.ContentLength - Response.ContentOut; //(3)
     
                if viSent > 16000 then viSent := 16000; //(4)
     
                Write(Read_File(vsFileName, Response.ContentOut, viSent) ); //(5)
              end
              else
                Disconnect; //(6)
            end
            else
              Write('File not found on server: ' + vsFileName); //(7)
          end;
        end;
    end;

    我们在做什么?

    • 检查是否必须发送更多数据。

    • 仅在文件大小未更改时才继续,否则则断开连接。

    • 计算仍然需要发送的文件内容大小。

    • 限制一次发送为16KB的长度。

    • 从文件(vsFileName)中发送viSent字节,从位置Response.ContentOut开始。

    • 断开客户端,因为文件已经更改,不断开将会发送错误的标题和文件。

    • 如果找不到文件,则会向客户端发送错误消息。

  6. 在OnDataSent事件中实现OnDataReceived事件。 

    必须为OnDataSent事件实现OnDataReceived事件。如果不这样做,那么我们的服务器将只发送Header和第一个16K的数据,并且转移永远不会结束。

    OnDataSent事件

  7. 编译并运行项目。

    现在可以编译并运行项目了。请记住,您可以将任何大文件放在data子目录中,它将仅使用16K而不是整个服务器的内存。

    服务器运行

    在浏览器中收到文件

DEMO4-Code

DEMO4发送大文件-PDF


慧都.jpg   

    关注慧聚IT微信公众号 ☟☟☟,了解产品的最新动态及最新资讯。

dd2629f30d553d56ccaf7164fdcb784e-sz_28327.webp.jpg



标签:

本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@wqylolg.cn

文章转载自:

为你推荐

  • 推荐视频
  • 推荐活动
  • 推荐产品
  • 推荐文章
  • 慧都慧问
扫码咨询


添加微信 立即咨询

电话咨询

客服热线
023-68661681

TOP