翻譯|使用教程|編輯:況魚杰|2019-07-30 16:53:09.013|閱讀 193 次
概述:本教程將會(huì)介紹創(chuàng)建一個(gè)能夠發(fā)送文件的Web服務(wù)器,無論其大小如何。在此過程中,我們必須小心服務(wù)器的內(nèi)存,服務(wù)器內(nèi)中可能有一個(gè)非常大的文件,不需要因?yàn)檫@個(gè)文件把所有的內(nèi)存都占用了。
# 界面/圖表報(bào)表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
相關(guān)鏈接:
RealThinClient SDK是用于開發(fā)標(biāo)準(zhǔn)的HTTP(S)服務(wù)器,ISAPI擴(kuò)展以及客戶端的VCL控件。可用于Windows下的CodeGear Delphi 6-2010。關(guān)于RealThinClient SDK的教程會(huì)持續(xù)更新,本節(jié)是RealThinClient SDK的第四課,如何從服務(wù)器發(fā)送小文件。
點(diǎn)擊下載最新版RealThinClient SDK
本教程將會(huì)介紹創(chuàng)建一個(gè)能夠發(fā)送文件的Web服務(wù)器,無論其大小如何。在此過程中,我們必須小心服務(wù)器的內(nèi)存,服務(wù)器內(nèi)中可能有一個(gè)非常大的文件,不需要因為這個(gè)文件把所有的內(nèi)存都占用了。
在前兩個(gè)示例中,我們一直在RtcDataProvider組件的OnCheckRequest和OnDataReceived事件上發(fā)送所有內(nèi)容。現(xiàn)在,為了能夠發(fā)送大內(nèi)容(大文件),除了我們從RtcDataProvider組件使用的事件之外,我們還需要OnDataSent事件。在先前調(diào)用Write函數(shù)準(zhǔn)備的所有數(shù)據(jù)都已發(fā)送到客戶端并且所有發(fā)送緩沖區(qū)都為空之后,將調(diào)用此事件。另外,我們需要對(duì)TRtcDataServer的Response屬性進(jìn)行一些檢查。
我們將使用第4課(感興趣的用戶也可以查看一下)開發(fā)的代碼作為基礎(chǔ),就能夠從我們的服務(wù)器發(fā)送大文件。我們?yōu)槊總€(gè)單個(gè)事件調(diào)用定義了16K的內(nèi)存限制,以便為從我們的服務(wù)器請求文件的任何客戶端保持服務(wù)器的內(nèi)存使用率低至16K。
接下來看看具體的步驟:
打開我們的第4課代碼。
更改我們的RtcDataProvider的OnCheckRequest事件。
我們將更改最后一個(gè)RtcDataProvider組件的OnCheckRequest事件,將Response.ContentLength值設(shè)置為文件大小。為此,請雙擊最后一個(gè)RtcDataProvider組件以跳轉(zhuǎn)到OnCheckRequest事件。事件只有一小部分,但為了將它們保存在一個(gè)地方,這里是完整的新事件實(shí)現(xiàn)的代碼:
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中所做的那樣,將文件名存儲(chǔ)在請求中,這樣不必在以后再次重新創(chuàng)建它。
需要設(shè)置Response.ContentLength,告訴RtcDataServer我們響應(yīng)中的內(nèi)容(數(shù)據(jù))有多大。如果不設(shè)置Response.ContentLength,RtcDataServer將假定調(diào)用Write的第一個(gè)事件來響應(yīng),并將計(jì)算ContentLength。
發(fā)送響應(yīng)標(biāo)頭,這樣就不必在文件大小為零的情況下調(diào)用Write。
更改我們的RtcDataProvider的OnDataReceived事件。
現(xiàn)在,我們將更新OnDataReceived我們的事件RtcDataProvider,為了只發(fā)送有限的數(shù)據(jù)量(我們設(shè)定該限制到16KB)。
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;
我們在做什么?
檢查是否必須發(fā)送更多數(shù)據(jù)。
僅在文件大小未更改時(shí)才繼續(xù),否則則斷開連接。
計(jì)算仍然需要發(fā)送的文件內(nèi)容大小。
限制一次發(fā)送為16KB的長度。
從文件(vsFileName)中發(fā)送viSent字節(jié),從位置Response.ContentOut開始。
斷開客戶端,因?yàn)槲募呀?jīng)更改,不斷開將會(huì)發(fā)送錯(cuò)誤的標(biāo)題和文件。
如果找不到文件,則會(huì)向客戶端發(fā)送錯(cuò)誤消息。
在OnDataSent事件中實(shí)現(xiàn)OnDataReceived事件。
必須為OnDataSent事件實(shí)現(xiàn)OnDataReceived事件。如果不這樣做,那么我們的服務(wù)器將只發(fā)送Header和第一個(gè)16K的數(shù)據(jù),并且轉(zhuǎn)移永遠(yuǎn)不會(huì)結(jié)束。
編譯并運(yùn)行項(xiàng)目。
現(xiàn)在可以編譯并運(yùn)行項(xiàng)目了。請記住,您可以將任何大文件放在data子目錄中,它將僅使用16K而不是整個(gè)服務(wù)器的內(nèi)存。
關(guān)注慧聚IT微信公眾號(hào) ???,了解產(chǎn)品的最新動(dòng)態(tài)及最新資訊。
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉(zhuǎn)載自: