- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个使用 Delphi 10.1 创建的 64 位服务器应用程序,在这个应用程序中我有一个 TIdTCPServer
组件。
当客户端连接时,线程计数会增加,而当客户端断开连接时,线程计数不会减少。此问题发生在 Windows Server 计算机上。我没有处理 OnConnect
和 OnDisconnect
事件中的任何代码。下面是我的 OnExecute
方法:
try
if not AContext.Connection.IOHandler.InputBufferIsEmpty then
begin
AContext.Connection.IOHandler.InputBuffer.ExtractToBytes(ReceivedIDBytes.PointerMessage.tyTIDBytes) ;
ReceivedIDBytes.ClientSocket := AContext.Connection;
MessageProcessorThread.ProcessMessageQueue.Enqueue(ReceivedIDBytes);
IndySleep(50);
end;
IndySleep(5);
except
end;
我应该使用 Application.ProcessMessages()
来解决此问题吗?
由于线程数增加,我需要定期重新启动服务器应用程序。
最佳答案
不要吞下异常! Indy 使用异常来报告套接字断开连接/错误等情况(EIdConnClosedGraceously
、EIdSocketError
等)。 TIdTCPServer 在内部处理其事件处理程序引发的未捕获异常,以了解何时清理管理已接受套接字的线程。通过吞咽异常,您将阻止 TIdTCPServer
正确执行清理操作。
如果您出于某种原因需要捕获异常(清理、日志记录等1),则至少应该重新引发从 EIdException
派生的任何异常。让 TIdTCPServer
处理 Indy 生成的异常,尤其是由于套接字断开连接而发生的异常。
1:考虑使用 TIdTCPServer.OnException
事件来代替。
try
if not AContext.Connection.IOHandler.InputBufferIsEmpty then
begin
AContext.Connection.IOHandler.InputBuffer.ExtractToBytes(ReceivedIDBytes.PointerMessage.tyTIDBytes);
ReceivedIDBytes.ClientSocket := AContext.Connection;
MessageProcessorThread.ProcessMessageQueue.Enqueue(ReceivedIDBytes);
IndySleep(50);
end;
IndySleep(5);
except
on E: Exception do
begin
...
if E is EIdException then
raise; // <-- add this!
end;
end;
我还建议删除 IndySleep()
调用。您实际上并不需要它们,让 Indy 在等待新数据到达时为您休眠:
try
if AContext.Connection.IOHandler.InputBufferIsEmpty then
begin
// the next call sleeps until data arrives or the specified timeout elapses...
AContext.Connection.IOHandler.CheckForDataOnSource(55);
AContext.Connection.IOHandler.CheckForDisconnect;
if AContext.Connection.IOHandler.InputBufferIsEmpty then Exit:
end;
AContext.Connection.IOHandler.InputBuffer.ExtractToBytes(ReceivedIDBytes.PointerMessage.tyTIDBytes);
ReceivedIDBytes.ClientSocket := AContext.Connection;
MessageProcessorThread.ProcessMessageQueue.Enqueue(ReceivedIDBytes);
except
on E: Exception do
begin
...
if E is EIdException then
raise;
end;
end;
或者,使用 TIdIOHandler.ReadBytes()
而不是直接使用 TIdBuffer.ExtractToBytes()
:
try
SetLength(ReceivedIDBytes.PointerMessage.tyTIDBytes, 0);
// the next call sleeps until data arrives or the IOHandler.ReadTimeout elapses...
AContext.Connection.IOHandler.ReadBytes(ReceivedIDBytes.PointerMessage.tyTIDBytes, -1, False);
if Length(ReceivedIDBytes.PointerMessage.tyTIDBytes) > 0 then
begin
ReceivedIDBytes.ClientSocket := AContext.Connection;
MessageProcessorThread.ProcessMessageQueue.Enqueue(ReceivedIDBytes);
end;
except
on E: Exception do
begin
...
if E is EIdException then
raise;
end;
end;
关于delphi - 当客户端连接到 TIdTCPServer 时线程数增加,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57364577/
我正在开发一个 voip 调用应用程序。我需要做的是在接到来电时将 Activity 带到前台。我在应用程序中使用 Twilio,并在收到推送消息时开始调用。 问题是我试图在接到任何电话时显示 Act
我是一名优秀的程序员,十分优秀!