GRPCを使ってチャットアプリケーションを開発しています。このアプリケーションでは、サーバーがクライアントから情報を受け取り、接続されているすべてのクライアントに送り返します。このために、私はサタニズムのchat-exampleを参考にしました。私はコードを複製して、コードをコンパイルして実行しますが、サーバーはクライアントからの要求を受け取りません。GRPCでリクエストとレスポンスを傍受/ログする
私の質問は:
- は失敗するかもしれないものとアウト&起こっているか、要求と応答を参照しGRPCにverbosサーバ側とクライアント側のログを有効にする方法はありますか?
- サーバーとクライアントに次のコードを使用しています。次のコードでは、クライアントとサーバーの間で通信が行われないことがあります。
WingokuServer.java
public class WingokuServer {
public static void main(String[] args) throws IOException, InterruptedException {
Server server = ServerBuilder.forPort(8091)
.intercept(recordRequestHeadersInterceptor())
.addService(new WingokuServiceImpl())
.build();
System.out.println("Starting server...");
server.start();
System.out.println("Server started!");
server.awaitTermination();
}
WingokuServerSideServiceImplementation:
public class WingokuServiceImpl extends WingokuServiceGrpc.WingokuServiceImplBase {
private static Set<StreamObserver<Response>> observers =
Collections.newSetFromMap(new ConcurrentHashMap<>());
public WingokuServiceImpl() {
System.out.println("WingokuServiceImp");
}
@Override
public StreamObserver<Request> messages(StreamObserver<Response> responseObserver) {
System.out.println("messages");
observers.add(responseObserver);
return new StreamObserver<Request>() {
@Override
public void onNext(Request request) {
System.out.println("Server onNext: ");
System.out.println("request from client is: "+ request.getRequestMessage());
Response response = Response.newBuilder().setResponseMessage("new Message From server at time: "+ System.nanoTime()).build();
for (StreamObserver<Response> observer : observers) {
observer.onNext(response);
}
}
@Override
public void onError(Throwable throwable) {
System.out.println("Server onError: ");
throwable.printStackTrace();
}
@Override
public void onCompleted() {
observers.remove(responseObserver);
System.out.println("Server onCompleted ");
}
};
}
}
WingokuClient:
public class WingokuClient {
public static void main(String[] args) {
ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 8091).usePlaintext(true).build();
WingokuServiceGrpc.WingokuServiceStub asyncStub = WingokuServiceGrpc.newStub(channel);
StreamObserver<Request> requestStreamObserver = asyncStub.messages(new StreamObserver<Response>() {
@Override
public void onNext(Response response) {
System.out.println("Client onNext");
System.out.println("REsponse from server is: "+ response.getResponseMessage());
}
@Override
public void onError(Throwable throwable) {
System.out.println("Client onError");
throwable.printStackTrace();
}
@Override
public void onCompleted() {
System.out.println("Client OnComplete");
}
});
requestStreamObserver.onNext(Request.newBuilder().setRequestMessage("Message From Client").build());
requestStreamObserver.onCompleted();
channel.shutdown();
System.out.println("exiting client");
}
}
編集:
コードは何も問題はありません。できます。クライアントのチャンネルにawaitTerminationを追加するだけで済みました。クライアントとサーバーの間の接続をただちに閉じるだけで、おそらくリクエストがクライアントからネットワークに出る前であったからです。そのため、サーバーは決して要求を受け取りませんでした。
しかし、冗長なロギングを有効にしたり、サーバー側にある種のインターセプターを追加したりするための私の質問はまだ解決されていません。だから私はここで専門家からいくつかの指摘を得ることを楽しみにしています。