或許你會有這樣的疑惑,大量的Transceiver Shell通訊組件在運行時被Port Builder創建,Transceiver Service的性能會高嗎?事實上,Port Builder的使命是在ServiceCreate事件發生時一次性完成的,Shell Port的數目只會影響Transceiver Service的初始化速度,Shell Port的通訊速度和Transceiver Servicer的整體性能將不受影響,當然系統資源可能會占用更多一些。
v. 事件的動態分配和處理
在Transceiver Shell所支持的若干種通訊Port當中,使用TServerSocket(可能您更傾向於使用Indy的通訊組件,但這並不違背Transceiver Service的設計思想,只是Shell層面的修改或增加而已)實現的TCPSource是比較有特點的一種,因為TServerSocket作為一種Source Port,不同於COM或POP3之類需要定時觸發的對象,它是在Transceiver Service啟動後時刻處於監聽狀態,當有ClIEntSocket連接並發送數據時產生相應事件的組件。以下是TCPSource的實例化片段:
begin //Create TCP/Receive Port
itmp:=high(TCPSource)+1;
SetLength(TCPSource,itmp+1);
TCPSource [itmp]:=TServerSocket.Create(self);
TCPSource [itmp].OnClientRead:=TCPServersClIEntRead;
//分配OnClientRead事件的處理過程為TCPServersClIEntRead
TCPSource [itmp].OnClientError:=TCPServerClIEntError;
//分配OnClientError事件的處理過程為TCPServerClIEntError
TCPSource [itmp].Name:= 'Receive'+inttostr(isource);
//設置Name屬性為'Receive'+Port ID
TCPSource [itmp].Tag:=itarget; //設置為其所在Channel的target ID
TCPSource [itmp].Socket.Data:=@ TCPSource [itmp].Tag;
//將此Port對象的target ID作為指針數據附於Socket對象上
……………
……………
end;
回來接著看我們的comSource的處理,在實例化時我們為其建立了觸發時鐘,但如何來處理時鐘觸發時的事件呢?同理,也是事件處理的動態分配。
comSource的時鐘的處理定義可在ServiceCreate事件處理中加入: application.OnMessage:=Timer;
實現對消息處理的重載,當有Application的消息產生時,Timer就將被觸發,在Timer事件中我們過濾處理時鐘觸發的WM_TIMER消息,就可以按Port ID和類型實現對特定Source Port的數據獲取方法的調用:
Procedure TCarrIEr.Timer(var Msg: TMsg; var Handled: Boolean);
var stmp:string;
Obj:TComponent;
begin
if Msg.message =WM_TIMER then//處理時鐘消息
begin//根據觸發消息的Port ID找到定義此消息的對象
Obj:=FindComponent('Receive'+inttostr(Msg.WParam));
if obj=nil then exit;//沒有找到就退出處理
stmp:=obj.ClassName;//反射獲得此Port對象的類型信息
if stmp='TIdPOP3' then GetPOP3(TIdPOP3(Obj));
if stmp='TIdFTP' then GetFTP(TIdFTP(obj));
if stmp='TFilePort' then GetFile(TFilePort(Obj));
if stmp='TCOMPort' then GetCOM(TCOMPort(Obj));
//調用COMSource的數據獲取過程
……………
……………
end;
end;
vi. 獲取數據