【问题标题】:EIdSocketError in release mode发布模式下的 EIdSocketError
【发布时间】:2011-12-05 15:24:18
【问题描述】:

我正在维护一个 SOAP 服务器(带有一个包含 THTTPSoapDispatcherTHTTPSoapPascalInvokerTWebModule TWSDLHTMLPublish)在 delphi-XE2 中,我找不到处理 EIDSocketError 的方法(不在调试模式下!)。

我什至不确定它是从哪里引发的......我知道它是在用户在等待服务器响应时断开连接后引发的(请求超时或客户端网络丢失)。

它肯定是由 IdHTTPWebBrokerBridge 组件引发的,所以我尝试从myIdHTTPWebBrokerBridge.OnException 处理它但没有成功。我在这里和那里读到它在调试模式下被引发但可以避免,但找不到关于如何在发布模式下处理它甚至阻止它被引发的线索......

如果需要,我可以在我的应用程序的请求部分提供代码。

MyService.exe

program MyService;
{$APPTYPE GUI}


{$R 'documents.res' 'documents.rc'}

uses
  Forms,
  Sysutils,
  WebReq,
  IdHTTPWebBrokerBridge,
  UFMyService in 'Unit\UFMyService.pas' {FMyService},
  UWMMyService in 'Unit\UWMMyService.pas' {WMMyService: TWebModule},
  UDMMyService in 'Unit\UDMMyService.pas' {DMMyService: TDataModule},
  UIMyService in 'Unit\UIMyService.pas',
  UCMyService in 'Unit\UCMyService.pas',
  superobject in 'Unit\superobject.pas',
  superxmlparser in 'Unit\superxmlparser.pas',


{$R *.res}
const
  se = '/';
begin
  if WebRequestHandler <> nil then
    WebRequestHandler.WebModuleClass := WebModuleClass;
  Application.Initialize;
  Application.Title := 'My Service';
  try
    Application.CreateForm(TFMyService, FMyService);
    Application.Run;
  Except on E:Exception do
    begin
      Log('!! Exception au lancement : '+E.Message);
      Application.Terminate;
    end;
  end;
end.

然后在

UFMyService.pas

unit UFMyService;

interface

uses (...)

type
  TFMyService = class(TForm)
    ApplicationEvents1: TApplicationEvents;
    procedure FormCreate(Sender: TObject);
    procedure ApplicationEvents1Exception(Sender: TObject; E: Exception);
(...)
  private
    FServer: TIdHTTPWebBrokerBridge;
    procedure handleException(AContext: TIdContext; AException: Exception);
(...)
  end;

var
  FMyService: TFMyService;

implementation

{$R *.dfm}

uses
  UWMMyService, UDMMyService, (...);

procedure TFMyService.ApplicationEvents1Exception(Sender: TObject; E: Exception);
begin
  if not(E is EIdConnClosedGracefully) and not (E is EIdConnClosedGracefully) then
  begin
    Log(e.Message);
  end;
end;

procedure TFMyService.FormCreate(Sender: TObject);
begin
  (...)
  FServer := TIdHTTPWebBrokerBridge.Create(Self);
  FServer.OnException := handleException;
  (...)
end;

procedure TFMyService.handleException(AContext: TIdContext; AException: Exception);
begin
  if not(AException is EIdSilentException) and not(AException is EIdConnClosedGracefully) then
  begin
    Log(AException.Message);
  end;
end;

[edit]

'时光倒流。

原来是 delphi 和它的 TWebRequestHandler 显示弹出窗口:

procedure TWebRequestHandler.HandleException(Sender: TObject);
var
  Handled: Boolean;
  Intf: IWebExceptionHandler;
begin
  Handled := False;
  if ExceptObject is Exception and
    Supports(Sender, IWebExceptionHandler, Intf) then
    try
      Intf.HandleException(Exception(ExceptObject), Handled);
    except
      Handled := True;
      System.SysUtils.ShowException(ExceptObject, ExceptAddr);
    end;
  if (not Handled) then
    System.SysUtils.ShowException(ExceptObject, ExceptAddr);
end;

我只是不知道如何自己处理异常......

如果我声明我的 WebModule 的 OnException,我可以记录异常,但无论我如何尝试处理/释放它,它仍然显示弹出窗口:

procedure TWMMyService.WebModuleException(Sender: TObject; E: Exception;
  var Handled: Boolean);
var
  AnError : TObject;
begin
  Log('!! WebModule Error ('+Sender.ClassName+')');
  Log('!! Type : '+E.ClassName);
  Log('!! Message : '+E.Message);
  Handled:=True;
// later add-on
  if( E is EIdSilentException) then
  begin
    //Socket 10054 Connection reset by peer.
    //etc...
    AnError := AcquireExceptionObject;
    if (AnError <> nil) then
    begin
      Log('!! Ignore Exception');
      ReleaseExceptionObject;
    end;
  end; // then the popup appears...
end;

达到Log('!! Ignore Exception');,但ReleaseExceptionObject无效;也许为时已晚。

我将 WebRequestHandler.MaxConnections 更改为 100 以防止客户端因这些套接字异常而过快地进行特技,但想象一下必须验证 100 弹出窗口才能继续工作......我就是不能这样 ^^

感谢大家的任何建议/建议/解决方案:)

[edit]

几个月后仍在寻找解决方案,没人知道吗?我厌倦了这个 Delphi 侵入性和令人厌烦的错误,因为它只能是这样!

【问题讨论】:

  • 代码非常繁重,我必须提供哪一部分?
  • 不要在 handleExceptio() 或 OnException 中释放异常。它将被调用 OnException 的异常处理程序释放。
  • 谢谢,我删除了这部分(但实际上我什至无法记录错误,所以我根本不输入 OnError 事件函数...)

标签: delphi exception delphi-xe2 webrequest indy


【解决方案1】:

为什么你需要处理异常? EIdSocketError 表示发生套接字错误。连接可能丢失或错误关闭。 Indy 服务器端连接是多线程的。套接字错误意味着套接字可能处于不稳定状态,需要关闭。让 Indy 在内部处理异常将停止连接的所属线程并为您关闭套接字。

【讨论】:

  • 我该怎么做,因为 indy 本身会引发错误并立即显示一个弹出窗口,该窗口会在显示 10 个左右弹出窗口后阻碍应用程序?如果我可以阻止它显示弹出窗口,它可能没有害处......无论如何,谢谢你阅读我^^
  • 对不起,该应用程序不是特技,但它不能接受更多的连接
  • 如果没有更多的情况,那么我必须指向数字 2... 我必须在哪里搜索那些“默认异常处理程序”?
  • #2 不太可能考虑到 Indy 服务器的多线程特性,除非您正在与代码中的主线程同步,或者您的主线程代码正在直接访问客户端连接。您只需在调试器中运行您的项目,即可查看异常实际上是从哪里引发的,以及导致异常的调用堆栈是什么样的。
  • 能否提供弹出消息的截图?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-15
  • 1970-01-01
  • 2019-03-17
  • 2017-04-13
  • 1970-01-01
  • 1970-01-01
  • 2021-07-17
相关资源
最近更新 更多