簡體   English   中英

如何在netty中設置不關閉連接的讀取超時?

[英]How to set a read timeout in netty that does not close the connection?

我有一個netty服務器接收來自客戶端的請求,向另一個服務器發出請求,然后在響應原始客戶端請求時使用第二個請求的響應。 我希望對第二個服務器的請求有一個短暫的超時(~40ms),因此我可以在超時的情況下發送一般響應,但我不想關閉與第二個服務器的連接。 相反,我只是在它到達時丟棄對超時請求的響應,然后將連接返回到我的池中。

在netty中執行此操作的最佳方法是什么? 我已經嘗試過ReadTimeoutHandler,但是當發生超時時,這似乎會關閉與第二台服務器的連接。

看來根據您的要求,您需要圍繞與第二台服務器的連接編寫自己的時序管理。 此外,既然你提到了一個連接池,這可能意味着你也可以限制你可以同時建立到第二台服務器的連接數量(好吧,總有一個限制,它只取決於你是否真的要擔心它或不)。

對於您不擔心排隊出站請求的簡單情況,您應該能夠創建ReadTimeoutHandler的副本並根據需要進行修改,最有可能的方法是讓它從上下文中獲取回調,以便調用而不是關閉readTimedOut()方法中的連接。

在您要對出站請求進行排隊的情況下,您應該考慮在隊列上花費的時間以及接收響應的時間,因此您的解決方案需要您自己的計時器,只要您將項目放入出站隊列。 此外,您需要一種在計時器和返回的有效結果之間進行同步的方法(您只想發送一個響應,而不是在計時器超時時發送一個響應,而在第二個服務器的響應進入時發送一個響應)。 要做到這一點,我想你會想要使用某種類型的管理器對象,它包含對通道的引用,你的回調通過這個管理器寫回來。

例如(在偽代碼中)

MyStateManager manager = new MyStateManager(channel);
// Scheduled a timer task for 40ms from now to invoke the callback
// method of your ReadTimedOutCallback and send a message through the manager
myTimer.schedule(new ReadTimedOutCallback(manager),40);
// Send an outbound request to server 2 through a class that queues
// and manages such requests asynchronously.  When the request is complete
// it invokes the callback method of RequestCompletedCallback which then
// sends a response through the manager.
myAsyncOutboundServerRequester.request(new RequestCompletedCallback(manager));
// ... finish and return the thread to Netty for use with other requests
// while the async tasks process

簡單形式的管理器就像(不包括異常處理,通道狀態檢查等):

public class MyStateManager
{
    private final Channel channel;
    private AtomicBoolean messageSent = new AtomicBoolean(false);
    public MyStateManager(Channel channel)
    {
        this.channel = channel;
    }

    // Called by the ReadTimeoutCallback
    public void sendGenericResponse()
    {
        if (messageSent.getAndSet(true))
        {
           //... write generic response to channel
           ChannelFuture future = channel.write... 
           // Add listeners to future, etc
        } 
    }

    // Called by the RequestCompletedCallback
    public void sendResponse(MyResponseObject response)
    {
        if (messageSent.getAndSet(true))
        {
            // write returned response to channel
            ChannelFuture future = channel.write(response);
            // Add listeners to future, etc
        }
    }

}

您可能仍然希望對第二台服務器的連接進行某種類型的超時檢查,以便在連接時間過長(30秒或一分鍾等)時無法響應連接。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM