2009-09-11 15 views
3

Indy를 TCP 통신 (D2009, Indy 10)으로 사용합니다.연결이 Indy에서 아직 살아 있는지 확인하려면 어떻게합니까?

클라이언트 요청을 평가 한 후 클라이언트에 응답을 보내려고합니다. 그래서 저는 TIdContext 같은이 (의사)를 저장

procedure ConnectionManager.OnIncomingRequest (Context : TIdContext); 
begin 
    Task := TTask.Create; 
    Task.Context := Context; 
    ThreadPool.AddTask (Task); 
end; 

procedure ThreadPool.Execute (Task : TTask); 
begin 
    // Perform some computation 
    Context.Connection.IOHandler.Write ('Response'); 
end; 

그러나 클라이언트가 요청 및 전송에 대한 준비가되는 답 사이의 어딘가에 연결을 종료하는 경우? 컨텍스트가 유효한지 어떻게 확인할 수 있습니까? 시도 :

if Assigned (Context) and Assigned (Context.Connection) and Context.Connection.Connected then 
    Context.Connection.IOHandler.Write ('Response'); 

그러나 도움이되지 않습니다. 어떤 경우에는 프로그램이 멈추고 실행을 일시 중지하면 현재 행이 if 조건을 가진 행이라는 것을 알 수 있습니다.

여기서 어떻게됩니까? 연결이 끊어진 상태로 보내려고하지 않으려면 어떻게해야합니까?

답변

4

좋아, 해결책을 찾았습니다. TIdContext를 저장하는 대신 TIdTcpServer에서 제공하는 컨텍스트 목록을 사용합니다.

procedure ThreadPool.Execute (Task : TTask); 
var 
    ContextList : TList; 
    Context : TIdContext; 
    FoundContext : Boolean; 
begin 
    // Perform some computation 

    FoundContext := False; 
    ContextList := FIdTCPServer.Contexts.LockList; 
    try 
    for I := 0 to ContextList.Count-1 do 
     begin 
     Context := TObject (ContextList [I]) as TIdContext; 
     if (Context.Connection.Socket.Binding.PeerIP = Task.ClientInfo.IP) and 
     (Context.Connection.Socket.Binding.PeerPort = Task.ClientInfo.Port) then 
     begin 
     FoundContext := True; 
     Break; 
     end; 
     end; 
    finally 
    FIdTCPServer.Contexts.UnlockList; 
    end; 

    if not FoundContext then 
    Exit; 

    // Context is a valid connection, send the answer 

end;   

그게 효과가 있습니다.

2

클라이언트가 연결을 닫으면 클라이언트 시스템/네트워크 카드가 죽거나 클라이언트와 클라이언트간에 다른 네트워크 문제가있는 경우 다음 번에 연결에 쓰려고 할 때까지 알지 못할 수 있습니다.

하트 비트를 사용할 수 있습니다. 연결이 여전히 유효한지 짧은 시간이 지남에 따라 때때로 클라이언트에 메시지를 보냅니다. 이렇게하면 예상치 못한 연결이 끊어지면 더 빨리 알 수 있습니다. "CheckConnection"함수로 포장하고 응답을 보내기 전에 호출 할 수 있습니다.

+0

문제는 TIdContext 및 연결에 액세스하면 응용 프로그램이 중단되고 테스트 연결 메시지가 아무런 차이가 없다는 것입니다. – jpfollenius

+0

시간 초과를 기다리고 있기 때문에 정지합니까? –

+0

인디 (Indy)가 너무 막혀서 앱이 멈춰있는 이유입니다. 클라이언트가 여전히 살아 있는지 확인하는 가장 좋은 방법은 클라이언트 "상태 메시지"를 수신하는 것입니다. 고객은 일정한 간격으로 체크인해야합니다. 클라이언트가 이러한 검사를 많이 수행하지 못하면 사용할 수없는 것으로 간주 할 수 있습니다. 또는 비 블로킹 라이브러리 (ICS)를 사용할 수 있으므로 응용 프로그램이 TCP 연결을 차단하지 않습니다. 연결을 기다리는 것이 앱이 응답하지 않는다는 의미는 아닙니다. 비 블로킹 소켓이나 스레드를 사용하십시오. – Runner

관련 문제