使用Remobjects的單通道做服務端項目時,每當同一用戶端同時發起超過一個以上的請求資料時,就會出現Channel is Busy 錯誤,為此我詢問過Remobjects官方,他們回答是,單通道是非多線程安全的,類似這樣的回答,建議我的用超級通道。可是簡單地更換單通道為超級通道反而導緻問題更多,由是我就想改造一下單通道。
在盒子上我曾經釋出關于這個問題解決方法,但是還不合理,現在貼出來最終的解決方法,這個方法在我的程式使用後,再也沒有出現以上問題
uROClient.pas内,請對照修改.
procedure TROTransportChannel.Dispatch(aRequest, aResponse : TStream);
var retry : boolean;
{$ifdef REMOBJECTS_UseEncryption}
EncRequest,EncResponse : TMemoryStream;
{$endif}
faultstartlocatoridx : integer;
lEvent: TROEvent;
ATime: Integer;
const
aIncment:Integer=10;
aMaxWaitTime:Integer =100000;
begin
retry := TRUE;
if not fThreadsafe then
_CriticalSection.Enter;//加上這一句,可能等到本次請求結束後,再執行下次請求。很實用。
try
if fBusy then raise EROChannelBusy.Create(err_ChannelBusy);
fBusy := TRUE;
end;
//removed because of a warning faultstartlocatoridx := -1;
faultstartlocatoridx := InitServerLocator;
if Assigned(fOnSendStream)
then fOnSendStream(aRequest);
repeat
try
aRequest.Position := 0;
{$IFDEF REMOBJECTS_UseEncryption}
if Encryption.EncryptionMethod <> tetNone then begin
EncRequest:= TMemoryStream.Create;
EncResponse := TMemoryStream.Create;
try
DoEncryption(aRequest,EncRequest);
IntDispatch(encRequest, encResponse);
DoDecryption(EncResponse,aResponse);
finally
EncRequest.Free;
EncResponse.free;
end;
end
else
{$ENDIF}
begin
IntDispatch(aRequest, aResponse);
end;