IceRPC之傳入響應和攔截器->快樂的RPC

xlgwr發表於2024-05-16

作者引言 .Net 8.0 下的新RPC

很高興啊,我們來到了IceRPC之傳入響應和攔截器->快樂的RPC, 基礎引導,讓自已不在迷茫,快樂的暢遊世界。

傳入響應 Incoming response

瞭解如何演繹傳入的響應。

收到傳入響應

呼叫器 invoker 非同步返回傳入響應。該傳入響應是由連線從對等點接收響應時建立的。

傳入響應包含哪些內容:

  • 狀態程式碼 status code
  • 錯誤訊息,僅在狀態程式碼不是OK時設定
  • 響應欄位 fields
  • 響應的有效負載 payload

狀態程式碼 Status code

狀態程式碼表示對等方傳送的狀態。Ok或錯誤都可以。StatusCodeSlice 中定義的列舉:

unchecked enum StatusCode : varuint62 {
    Ok = 0
    ApplicationError
    NotFound
    NotImplemented
    ... more errors ...
}

消耗響應的呼叫者,使用此狀態程式碼來計算響應有效負載 payload 的內容。例如,當呼叫者是由 Slice 編譯器生成的程式碼時,它將 Ok 時,意味著響應payload持有 Slice 編碼的返回值。

響應欄位 fields

響應欄位表示響應攜帶的帶外資訊。這些欄位通常由中介軟體middleware和攔截器interceptors讀取和寫入,以協調伺服器和客戶端中相同響應的處理。

欄位是字典 ResponseFieldKey 中位元組序列的條目,其中 ResponseFieldKey 是在 Slice 中定義的列舉。

unchecked enum ResponseFieldKey : varuint62 {
    CompressionFormat = 2
    ...
}

例如,當壓縮中介軟體壓縮傳出響應的有效負載時,它會設定響應欄位 CompressionFormat。這告訴連線另一側的壓縮機攔截器"該有效載荷被 brotli 壓縮";然後壓縮攔截器可以解壓縮該(傳入)響應有效負載。

有效負載響應 Response payload

傳入響應的有效負載是表示操作返回值的位元組流。IceRPC而言,該流中的位元組數是未知的。

攔截器 Interceptor

瞭解如何編寫攔截器以及如何在呼叫管道中安裝攔截器。

攔截傳出的請求

攔截器是在透過網路連線傳送傳出請求之前攔截傳出請求的程式碼。 相同的程式碼還會在遠端服務到達呼叫者之前攔截它返回的傳入響應。

在技術層面上,攔截器是持有另一個呼叫器(next)並在下一個呼叫器上呼叫,呼叫的呼叫器invoke,作為其自己的呼叫方法實現的一部分。
下一個呼叫器可以是客戶端連線、連線快取、另一個攔截器或其他型別的呼叫器;就攔截器而言,它只是另一個呼叫器。

攔截器可以在呼叫下一個呼叫器呼叫呼叫之前(在傳送請求之前)和呼叫下一個呼叫器呼叫呼叫之後(在收到響應之後)包含邏輯。 攔截器還可以使呼叫管道短路,返回快取響應或丟擲異常。

例如,一個簡單的 C# 攔截器可能如下所示:

public class SimpleInterceptor : IInvoker
{
    private readonly IInvoker _next;

    public SimpleInterceptor(IInvoker next) => _next = next;

    public async Task<IncomingResponse> InvokeAsync(OutgoingRequest request, CancellationToken cancellationToken)
    {
        Console.WriteLine("before _next.InvokeAsync");
        IncomingResponse response = await _next.InvokeAsync(request, cancellationToken);
        Console.WriteLine($"after _next.InvokerAsync; the response status code is {response.StatusCode}");
        return response;
    }
}

安裝攔截器

C# 中,可以透過建立類 Pipeline 的例項,然後呼叫 Use{Name} 擴充套件方法來建立呼叫管道,以便在此管道上安裝攔截器。

例如:

Pipeline pipeline = new Pipeline()
    .UseLogger(loggerFactory)
    .UseCompressor()
    .Into(clientConnection);

需要使用 Into 指定管道的最後一個呼叫器。 它通常是客戶端連線或連線快取,但它也可以是另一個管道,因為 Pipeline 本身就是呼叫器。
當在管道上進行呼叫時,請求會經過該呼叫器鏈。在返回的途中,傳入的響應以相反的順序穿過同一條呼叫者鏈。

--- title: An invocation pipeline with Logger, Compressor and ClientConnection --- flowchart LR app([application code]) -- request --> i1[Logger] -- request --> i2[Compressor] i2 -- request --> ti["client connection"] -- request --> connection connection -- response --> ti -- response --> i2 -- response --> i1 -- response --> app

安裝這些攔截器的順序很重要。 安裝的第一個攔截器是第一個執行的攔截器。透過上面建立的管道,日誌攔截器首先執行,然後在壓縮攔截器上呼叫 InvokeAsync,最後壓縮攔截器在客戶端連線上呼叫 InvokeAsync

作者結語

  • 一直做,不停做,才能提升速度
  • 翻譯的不好,請手下留情,謝謝
  • 如果對我有點小興趣,如可加我哦,一起探討人生,探討道的世界
  • 覺得還不錯的話,點個
    image

相關文章