我的网络服务是用delphi编写的。有时其中一些需要很长时间才能做出回应我想在客户端为他们设置30秒的超时时间。 鉴于我所有的服务器调用都是通过单独的线程完成的,我如何实现超时设置。
我目前正在使用SELECT c.id, dsv63.name AS 102
进行HTTP请求。
答案 0 :(得分:1)
您没有说明您用于沟通的组件。
我使用THTTPReqResp进行SOAP通信并执行此操作:
constructor TEWSSOAPMessage.Create(AWebserviceURL,AUserName,APassword: String; AExchangeTimeOutConnect,AExchangeTimeOutSend,AExchangeTimeOutReceive: Integer);
begin
FSoapRequest := TStringStream.Create('',TEncoding.UTF8);
FSoapRequest.Position := 0;
FSoapResponse := TStringStream.Create('',TEncoding.UTF8);
FSoapResponse.Position := 0;
FReqResp := THTTPReqResp.Create(nil);
FReqResp.URL := AWebserviceURL;
FReqResp.UserName := AUserName;
FReqResp.Password := APassword;
if AExchangeTimeOutConnect > 0 then FReqResp.ConnectTimeout := AExchangeTimeOutConnect;
if AExchangeTimeOutSend > 0 then FReqResp.SendTimeout := AExchangeTimeOutSend;
if AExchangeTimeOutReceive > 0 then FReqResp.ReceiveTimeout := AExchangeTimeOutReceive;
...
end;
如果我指定0,则会留下默认超时。
我填写FSoapRequest,然后当我执行'我的TEWSSOAPMessage:
procedure TEWSSOAPMessage.Execute;
begin
try
FExecTime := GetTickCount;
FReqResp.Execute(FSoapRequest,FSoapResponse);
FExecTime := GetTickCount - FExecTime;
...
except
on E:Exception do
begin
// WinINet error codes https://msdn.microsoft.com/en-us/library/microsoft.exchange.webservices.data.serviceerror%28v=exchg.80%29.aspx
if (E is ESOAPHTTPException) and (ESOAPHTTPException(E).StatusCode = ERROR_INTERNET_TIMEOUT) then
begin
FExecTime := GetTickCount - FExecTime;
FErrorMsg := Format(' TIMEOUT (%d msec) %s',[FExecTime,sErrExchangeTimeOutINI]);
end;
...
end;
end;
end; { Execute }
对于Delphi XE2 ERROR_INTERNET_TIMEOUT
在Winapi.WinInet
中声明,ESOAPHTTPException
在Soap.SOAPHTTPTrans
作为旁注,请确定您的超时时间(来自here):
procedure TFrmWininetTimeOuts.FormShow(Sender: TObject);
var
hSession : HINTERNET;
dwTimeOut : DWORD;
lBuflen : Cardinal;
begin
hSession := InternetOpen('usersession', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
if not Assigned(hSession) then Exit;
try
lBufLen := SizeOf(dwTimeOut);
if InternetQueryOption(hSession, INTERNET_OPTION_CONNECT_TIMEOUT, @dwTimeOut, lBufLen) then
Edit1.Text := IntToStr(dwTimeOut);
if InternetQueryOption(hSession, INTERNET_OPTION_SEND_TIMEOUT, @dwTimeOut, lBufLen) then
Edit2.Text := IntToStr(dwTimeOut);
if InternetQueryOption(hSession, INTERNET_OPTION_RECEIVE_TIMEOUT, @dwTimeOut, lBufLen) then
Edit3.Text := IntToStr(dwTimeOut);
finally
InternetCloseHandle(hSession);
end;
end;
答案 1 :(得分:1)
首先,如果您还没有设置超时:
var
MyRIO: THTTPRIO;
begin
MyRio := ...
MyRIO.HTTPWebNode.ConnectTimeout:=x;
MyRIO.HTTPWebNode.SendTimeout :=x;
MyRIO.HTTPWebNode.ReceiveTimeout:=x;
end;
如果这不起作用,请进一步挖掘。
据我所知,THTTPRIO的问题在于,至少在Windows上,它使用或曾经使用过WinINET,而WinINET中有许多潜在的错误,包括无法尊重所请求的任何超时。出于这个原因,我放弃了使用WinINET的任何东西。您使用的是哪个版本的Delphi?我想在某些时候,THTTPRIO可能已经从WinINET(这是废话)转移到WinHTTP(这很好),但是根据你的Delphi版本,你可能想要检查一下发生了什么。在Android和iOS上,当然,在Mac firemonkey上,WinINET是不可能的,但如果你在Windows上进行测试及其出现故障,请考虑这种可能性。我相信,通过Delphi XE8和10西雅图,默认情况下,THINTPRIO不会使用WinINET,但是我无法在此找到文档。