在 Grpc-Android Java 中使用双向流时如何检测(物理)断开连接

How to detect (physical) disconnect when using a bidirectional stream in Grpc-Android Java

我使用 Bidirectional Streaming 的概念 Grpc 使用 Async stub

以下是我的代码

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    btnOnline = (Button) findViewById(R.id.btnOnline);
    btnOffline = (Button) findViewById(R.id.btnOffline);
    btnAcceptRide = (Button) findViewById(R.id.btnAcceptRide);
    btnCancelRide = (Button) findViewById(R.id.btnCancelRide);
    txtCode = (EditText) findViewById(R.id.txtCode);
    txtReply = (TextView) findViewById(R.id.txtReply);
    ClientConnState = 0;
    btnOnline.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            new GrpcTask().execute();

        }
    });
  private class GrpcTask extends AsyncTask<Void, Void, String> {
    private String mHost;
    private String mMessage;
    private int mPort;
    private ManagedChannel mChannel;

    @Override
    protected void onPreExecute() {
        mHost = "localhost";
        mPort = 8080;
        mChannel = ManagedChannelBuilder.forAddress("192.168.0.102", 50049)
                .usePlaintext(true)
                .build();
        blockingStub = bidirectionalserviceGrpc.newBlockingStub(mChannel);
        asyncStub = bidirectionalserviceGrpc.newStub(mChannel);
    }

    @Override
    protected String doInBackground(Void... nothing) {
        try {
            final CountDownLatch countDownLatch = new CountDownLatch(1);
            requestStreamObserver = asyncStub.requestRide(new StreamObserver<Bidirectional.RideReply>() {
                @Override
                public void onNext(Bidirectional.RideReply value) {
                    if (countDownLatch.getCount() > 0) {
                        countDownLatch.countDown();
                    }                     
                }

                @Override
                public void onError(Throwable t) {
                    countDownLatch.countDown();
                }

                @Override
                public void onCompleted() {
                    countDownLatch.countDown();
                }
            });
            Bidirectional.RideRequest rideRequest = Bidirectional.RideRequest.newBuilder()
                    .setRequestid(1)
                    .setDrivercode(txtCode.getText().toString())
                    .build();
            requestStreamObserver.onNext(rideRequest);
            if (!countDownLatch.await(15, TimeUnit.SECONDS)) {
                throw new RuntimeException(
                        "Could not finish rpc within 1 minute, the server is likely down");
            }
            return "completed";
        } catch (Exception e) {
            StringWriter sw = new StringWriter();
            PrintWriter pw = new PrintWriter(sw);
            e.printStackTrace(pw);
            pw.flush();
            return "Failed... : " + System.lineSeparator() + sw;
        }
    }

    @Override
    protected void onPostExecute(String result) {
        Log.e(logger.getName(), result);
    }
}
  final Handler handler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        // Write Logic here
        super.handleMessage(msg);
    }
};

现在一切正常.. 我可以 ping/pong server/client 使用已建立的流。但是当我关闭服务器并从客户端发出流请求时,它会无限等待。我除了它抛出 OnError() 事件但它没有。

有人可以帮我解决这个问题吗?

根据服务器如何关闭以及客户端正在做什么,TCP 可能无法发现连接中断。您应该在 ManagedChannelBuilder 上启用 keepAliveTime()。 Javadoc 应该可以帮助您入门,如果您有兴趣,A8-client-side-keepalive.md 有更多信息。

您可能还想启用 idleTimeout()