Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/214.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Grpc Android Java中使用双向流时如何检测(物理)断开连接_Java_Android_Grpc_Grpc Java - Fatal编程技术网

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

在Grpc Android Java中使用双向流时如何检测(物理)断开连接,java,android,grpc,grpc-java,Java,Android,Grpc,Grpc Java,我使用了双向流概念,即Grpc使用异步存根 下面是我的代码 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btnOnline = (Button) findViewById(R.id.btnOnline); btnOffline = (

我使用了
双向流
概念,即
Grpc
使用
异步存根

下面是我的代码

@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);
    }
};
@覆盖
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnOnline=(按钮)findViewById(R.id.btnOnline);
btnOffline=(按钮)findViewById(R.id.btnOffline);
btnAcceptRide=(按钮)findViewById(R.id.btnAcceptRide);
btnCancelRide=(按钮)findViewById(R.id.btnCancelRide);
txtCode=(EditText)findViewById(R.id.txtCode);
txtReply=(TextView)findViewById(R.id.txtReply);
ClientConnState=0;
btnOnline.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图){
新建GrpcTask().execute();
}
});
私有类GrpcTask扩展了AsyncTask{
私有字符串mHost;
私有字符串消息;
私人进口;
专用管理频道mcchannel;
@凌驾
受保护的void onPreExecute(){
mHost=“localhost”;
mPort=8080;
McChannel=ManagedChannel Builder.forAddress(“192.168.0.102”,50049)
.usePlaintext(真)
.build();
blockingStub=双向服务GRPC.新blockingStub(MCChannel);
asyncStub=双向服务GRPC.newStub(MCChannel);
}
@凌驾
受保护的字符串doInBackground(无效…无){
试一试{
最终倒计时锁存器倒计时锁存器=新倒计时锁存器(1);
requestStreamObserver=asyncStub.requestRide(新的StreamObserver(){
@凌驾
public void onNext(双向.RideReply值){
如果(countDownLatch.getCount()>0){
countdownlock.countDown();
}                     
}
@凌驾
公共作废登记员(可丢弃的t){
countdownlock.countDown();
}
@凌驾
未完成的公共无效(){
countdownlock.countDown();
}
});
双向.RideRequest RideRequest=双向.RideRequest.newBuilder()
.setRequestid(1)
.setDrivercode(txtCode.getText().toString())
.build();
requestStreamObserver.onNext(rideRequest);
如果(!countDownLatch.Wait(15,时间单位秒)){
抛出新的运行时异常(
“无法在1分钟内完成rpc,服务器可能已关闭”);
}
返回“已完成”;
}捕获(例外e){
StringWriter sw=新的StringWriter();
PrintWriter pw=新的PrintWriter(sw);
e、 printStackTrace(pw);
pw.flush();
返回“Failed…”“+System.lineSeparator()+sw;
}
}
@凌驾
受保护的void onPostExecute(字符串结果){
Log.e(logger.getName(),result);
}
}
最终处理程序=新处理程序(){
@凌驾
公共无效handleMessage(消息消息消息){
//在这里写逻辑
超级handleMessage(msg);
}
};
现在一切都正常了。我可以使用已建立的流对服务器/客户端进行ping/pong。但当我关闭服务器并从客户端发出流请求时,它会无限期地等待。我希望它抛出
OnError()
事件,但它不会


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

根据服务器的运行方式和客户端的操作,TCP可能不会发现连接中断。您应该在
ManagedChannel Builder
上启用
keepAliveTime()
。Javadoc应该让您开始使用,如果您感兴趣,它会提供更多信息

您可能还希望启用
idleTimeout()