0

GETサーバーにリクエストを送信して新しいメッセージを受信する deplhi プロジェクトにライブ チャットを実装しています。新しいメッセージが発生しない場合、サーバー自体は 20 秒後に接続を閉じます。上記のコードは別のスレッド (チャットの「ページ」にアクセスすると作成される) にあるため、GUI がフリーズすることはありません。チャットからチャット以外のページに移動thread_chatすると、スレッドを終了させるために外部でこのコードを呼び出します。

if thread_chat <> nil then
begin
  thread_chat.Terminate;
  thread_chat := nil;
end;

ただし、サーバーのタイムアウトは 20 秒であるため、スレッドは実際には応答を受信した場合にのみ閉じます (私のスレッド ループは であるため、これは論理的に聞こえますwhile not Terminated do)。だから私が探しているのは、リクエストの途中でHTTP接続を閉じることです。

試み #1

TerminateThread最初は、次のように呼び出して調べました

TerminateThread(thread_chat.Handle, 0)

これは、2回目にスレッドを強制終了しようとするまで正常に機能します-アプリが完全にフリーズします。だから私はに行きました

試み #2

グローバル変数を作成し、次のURL_HTTP: TIdHTTP関数でサーバー ページのコンテンツを受け取ります。

function get_URL_Content(const Url: string): string;
var URL_stream: TStringStream;
begin
  URL_HTTP := TIdHTTP.Create(nil);
  URL_stream := TStringStream.Create(Result);
  URL_HTTP.Get(Url, URL_stream);
  if URL_HTTP <> nil then
  try
    URL_stream.Position := 0;
    Result := URL_stream.ReadString(URL_stream.Size);
  finally
    FreeAndNil(URL_HTTP);
    FreeAndNil(URL_stream);
  end;
end;

そして、このコードを外部で呼び出すとthread_chat

if thread_chat <> nil then
begin
  URL_HTTP.Disconnect;
  thread_chat.Terminate;
end;

例外がEidClosedSocket発生します(この投稿を書いているときにいくつかのテストを行った後、EAccessViolation代わりにエラーが発生します)。

アイデアが尽きた。サーバーの応答前に HTTP 要求を閉じるにはどうすればよいですか?


procedure thread_chat.Execute;  //overrided
begin
    while not Terminated do
      if check_messages then  //sends request to the server, processes response, true if new message(s) exist
        show_messages;
end;
4

1 に答える 1