【Grpc(一)】Java 何如理解StreamObserver?

剛開始接觸Grpc時,樁代碼裏有許多StreamObserver類型,不太清楚是怎麼用的,這裏做一個記錄。

首先看下StreamObserver接口定義:

public interface StreamObserver<V>  {
    void onNext(V value);
    void onError(Throwable t);
    void onCompleted();
}

可以看到,這是一個泛型化的回調接口,並且從命名上看,該接口使用了觀察者模式。提到回調,或者提到觀察者模式,首先可以想到,這裏面涉及到兩個角色:觀察者和被觀察者。被觀察者負責在某一事件發生時調用回調函數通知觀察者,觀察者負責提供回調函數。對於需要被觀察的事件,這裏是作爲回調接口裏的泛型變量存在的。這就是這個接口的使用流程。下面結合Grpc裏的幾個使用場景來看下。
1.服務端方法實現返回值例子:
我們可以看一個簡單的unary模式的返回值:

@Override
public void getByKey(MyRequest request, StreamObserver<MyResponse> responseObserver) {
    int key = request.getKey();
    String value = ""; // 計算邏輯

    responseObserver.onNext(MyResponse.newBuilder().setValue(value).build());
    responseObserver.onCompleted();
}

該實現方法裏定義了一個MyResponse類型的返回值,這個返回值是被關注的對象。方法參數裏有一個StreamObserver<MyResponse>的變量,該變量就是回調函數。回調函數由誰提供?也就是觀察者是誰?答案是Grpc框架。可以理解爲Grpc框架層在關注MyResponse類型的返回值的生成,然後使用協議層及io層做數據發送。我們可以大致看一下回調函數的實現,比如onNext方法:

@Override
public void onNext(RespT response) {
  if (cancelled) {
    if (onCancelHandler == null) {
      throw Status.CANCELLED.withDescription("call already cancelled").asRuntimeException();
    }
    return;
  }
  checkState(!aborted, "Stream was terminated by error, no further calls are allowed");
  checkState(!completed, "Stream is already completed, no further calls are allowed");
  if (!sentHeaders) {
    call.sendHeaders(new Metadata());
    sentHeaders = true;
  }
  call.sendMessage(response);
}

實現類是ServerCallStreamObserverImpl,其中的onNext、onError以及onComplete方法均會調用內部的ServerCall實例發送消息。具體發送邏輯實現這裏不做深入,總之可以明確的是,這裏的StreamObserver回調接口,其實現邏輯就是將消息發送至客戶端,這就是觀察者的邏輯。再看下被觀察者,也就是StreamObserver回調接口的調用方。其實就是實現類裏返回值的生成的邏輯,我們需要根據request取到參數,然後生成返回值,調用StreamObserver回調接口,來通知Grpc框架層發送返回值。至此服務端實現方法裏的StreamObserver已經清晰了:被觀察的對象就是返回值,Grpc框架層是觀察者,提供發送邏輯作爲回調函數,實現類是被觀察者,每一次返回值的生成都會調用回調函數通知Grpc。還有一點,StreamObserver接口的定義其實和stream息息相關。我們知道stream模式意味着可以在一個連接中發送多條消息,所以該接口提供了onNext回調函數,該函數可以被多次調用,每一次對onNext的調用都代表一條消息的發送。如果全部發送完了或者發送出錯,那麼就需要調用onError或者onComplete來告知對方本次stream已經結束。所以該接口的設計也與stream的概念也完全契合。
2.流式客戶端例子:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章