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;