Remobjects关于Channel is Busy 错误的解决方法

使用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
begin
if fBusy then raise EROChannelBusy.Create(err_ChannelBusy);
fBusy := TRUE;
end;
//removed because of a warning faultstartlocatoridx := -1;

faultstartlocatoridx := InitServerLocator;

try
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;

aResponse.Position := 0;
if Assigned(fOnReceiveStream) then begin
fOnReceiveStream(aResponse);
aResponse.Position := 0;
end;

Exit;
except
on E:Exception do begin
retry := FALSE;

ChangeServerLocator(faultstartlocatoridx,retry,E);
//if not retry then begin
//if Assigned(fOnException) then fOnException(Self, E, retry);
if not retry then raise;
//end;
end;
end;
until not retry;
finally
if not fThreadSafe then
fBusy := FALSE;
end;
finally
if not fThreadSafe then
_CriticalSection.Release;
end;
end;

posted @ 2011-08-26 01:12  Max Woods  阅读(723)  评论(2编辑  收藏  举报