【问题标题】:Can only make one grpc request then application freezes只能发出一个 grpc 请求然后应用程序冻结
【发布时间】:2020-04-04 01:56:08
【问题描述】:

我正在尝试使用 grpc 实现客户端和服务器。当我向服务器发送请求时,我得到了响应,但是当我尝试发送另一个请求时,应用程序冻结或只是不断地说它正在寻找我请求的项目。我对此很陌生,所以不知道发生了什么。这是我在服务器中实现的方法:

package CarParkOperations.proto.cp;

import java.io.IOException;
import java.util.ArrayList;
import java.util.logging.Logger;

import io.grpc.Server;
import io.grpc.ServerBuilder;
import io.grpc.stub.StreamObserver;
import java.util.Collection;

public class CarParkService extends carParkServiceGrpc.carParkServiceImplBase{
    private static final Logger logger = Logger.getLogger(CarParkService.class.getName());



     private Server server;

     private void start() throws IOException {
            /* The port on which the server should run */
            int port = 3000;

            server = ServerBuilder.forPort(port)
                .addService(new CarParkService())
                .build()
                .start();

            logger.info("Server started, listening on " + port);

            Runtime.getRuntime().addShutdownHook(new Thread() {
              @Override
              public void run() {
                System.err.println("*** shutting down gRPC server since JVM is shutting down");
                CarParkService.this.stop();
                System.err.println("*** server shut down");
              }
            });
          }

          private void stop() {
            if (server != null) {
              server.shutdown();
            }
          }

          /**
           * Await termination on the main thread since the grpc library uses daemon threads.
           */
          private void blockUntilShutdown() throws InterruptedException {
            if (server != null) {
              server.awaitTermination();
            }
          }

          /**
           * Main launches the server from the command line.
           */
          public static void main(String[] args) throws IOException, InterruptedException {
            final CarParkService server = new CarParkService();
            server.start();
            server.blockUntilShutdown();
          }

    public void showStatus(carparkRequest request, StreamObserver<carParkResponse> rStreamObserver) {
        for(CarParkOperations.proto.cp.CarPark c : Car.getInstance()) {
            if(c.getCarParkId() == request.getCarParkId()) {
                carParkResponse response = carParkResponse.newBuilder().setCarPark(c).build();
                rStreamObserver.onNext(response);
                rStreamObserver.onCompleted();
                return;
            }
        }   
    }

    @Override
    public void allCarParks(allCarp rAllCarp, StreamObserver<carParkResponse> rStreamObserver) {
        ArrayList<CarParkOperations.proto.cp.CarPark> carList = Car.getInstance();
        for (CarParkOperations.proto.cp.CarPark car : Car.carparkCar) {
            carParkResponse response = carParkResponse.newBuilder().setCarPark(car).build();
                if(car.getStatus() == rAllCarp.getStatus()) {
                    rStreamObserver.onNext(response);
                }
        }
        rStreamObserver.onCompleted();
    }

    public void setFull(CarParkToUpdateRequest request, StreamObserver<carParkResponse> rStreamObserver) {
        ArrayList<CarParkOperations.proto.cp.CarPark> carList = Car.getInstance();
            for(CarParkOperations.proto.cp.CarPark c : carList) {
                if(c.getCarParkId() == request.getDeviceId()) {
                    Car.carparkCar.clear();
                    Car.carparkCar.add(CarParkOperations.proto.cp.CarPark.newBuilder().setCarParkId(c.getCarParkId()).setLocation(c.getLocation()).setStatus("Full").build());
                    for(CarParkOperations.proto.cp.CarPark car : Car.carparkCar) {
                        carParkResponse response = carParkResponse.newBuilder().setCarPark(car).build();
                        rStreamObserver.onNext(response);
                        rStreamObserver.onCompleted();
                        return;
                    }
                }
            }
    }
    public void setSpaces(CarParkToUpdateRequest request, StreamObserver<carParkResponse> rStreamObserver) {
        ArrayList<CarParkOperations.proto.cp.CarPark> carList = Car.getInstance();
        for(CarParkOperations.proto.cp.CarPark c : carList) {
            if(c.getCarParkId() == request.getDeviceId()) {
                Car.carparkCar.clear();
                Car.carparkCar.add(CarParkOperations.proto.cp.CarPark.newBuilder().setCarParkId(c.getCarParkId()).setLocation(c.getLocation()).setStatus("Spaces").build());
                for(CarParkOperations.proto.cp.CarPark car : Car.carparkCar) {
                    carParkResponse response = carParkResponse.newBuilder().setCarPark(car).build();
                    rStreamObserver.onNext(response);
                    rStreamObserver.onCompleted();
                    return;
                }
            }
        }   
    }

}

这些是我在客户端中实现的方法:

     public void showStatus(int id) {
          channel =ManagedChannelBuilder.forAddress("localhost", 3000)
                    // Channels are secure by default (via SSL/TLS). For the example we disable TLS to avoid
                    // needing certificates.
                    .usePlaintext()
                    .build();
          blockingStub = carParkServiceGrpc.newBlockingStub(channel);
            asyncStub = carParkServiceGrpc.newStub(channel);
             logger.info("Will try to get CarPark " + id + " ...");
             carparkRequest request = carparkRequest.newBuilder().setCarParkId(id).build();
             carParkResponse response;
             try {
                 response = blockingStub.showStatus(request);
             }catch(StatusRuntimeException e) {
                 logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus());
                  return;
             }finally {
                channel.shutdown();
            }
             logger.info("Carpark: " + response.getCarPark());
            statusArea.append(response.getCarPark().toString());
     }





     public void setFull(int id) {
          channel =ManagedChannelBuilder.forAddress("localhost", 3000)
                    // Channels are secure by default (via SSL/TLS). For the example we disable TLS to avoid
                    // needing certificates.
                    .usePlaintext()
                    .build();
          blockingStub = carParkServiceGrpc.newBlockingStub(channel);
          asyncStub = carParkServiceGrpc.newStub(channel);
             logger.info("Will try to get CarPark " + id + " ...");
             CarParkToUpdateRequest request = CarParkToUpdateRequest.newBuilder().setDeviceId(id).build();
             carParkResponse response;
             try {
                 response = blockingStub.setFull(request);
             }catch(StatusRuntimeException e) {
                 logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus());
                  return;
             }finally {
                channel.shutdown();
             }
             logger.info("Carpark: " + response.getCarPark());
             fullArea.append(response.getCarPark().toString());
     }





     public void allCarParks(String status) {
         channel =ManagedChannelBuilder.forAddress("localhost", 3000)
                    // Channels are secure by default (via SSL/TLS). For the example we disable TLS to avoid
                    // needing certificates.
                    .usePlaintext()
                    .build();
            blockingStub = carParkServiceGrpc.newBlockingStub(channel);
            asyncStub = carParkServiceGrpc.newStub(channel);
             logger.info("Will try to get CarPark " + status + " ...");

             allCarp request =
                     allCarp.newBuilder().setStatus(status).build();
            Iterator<carParkResponse> carResponse;
            try {
                carResponse = blockingStub.allCarParks(request);
              for (int i = 1; carResponse.hasNext(); i++) {
                  carParkResponse carResponse1 = carResponse.next();
                  info("Result #" + i + ": {0}", carResponse1);
                if (testHelper != null) {
                  testHelper.onMessage(carResponse1);
                }
              }
            } catch(StatusRuntimeException e) {
                 logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus());
                  return;
            }
          }
     public void setSpaces(int id) {
          channel =ManagedChannelBuilder.forAddress("localhost", 3000)
                    // Channels are secure by default (via SSL/TLS). For the example we disable TLS to avoid
                    // needing certificates.
                    .usePlaintext()
                    .build();
          blockingStub = carParkServiceGrpc.newBlockingStub(channel);
            asyncStub = carParkServiceGrpc.newStub(channel);
             logger.info("Will try to get CarPark " + id + " ...");
             CarParkToUpdateRequest request = CarParkToUpdateRequest.newBuilder().setDeviceId(id).build();
             carParkResponse response;
             try {
                 response = blockingStub.setSpaces(request);
             }catch(StatusRuntimeException e) {
                 logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus());
                  return;
             }finally {
                    channel.shutdown();
                }
             logger.info("Carpark: " + response.getCarPark());
             spacesArea.append(response.getCarPark().toString());
     }

这是原始文件:

syntax = "proto3";

package CarParkOperations;

option java_package = "CarParkOperations.proto.cp";
option java_multiple_files = true;
option java_outer_classname = "ClassName";

service carParkService{
rpc showStatus(carparkRequest) returns (carParkResponse) {};
rpc setFull(CarParkToUpdateRequest) returns (carParkResponse){};
rpc setSpaces(CarParkToUpdateRequest) returns (carParkResponse){};
rpc allCarParks(allCarp) returns (stream carParkResponse){};
}

message CarPark{
int32 carPark_id = 1;
string status =2;
string location =3;

}

message carparkRequest{
int32 carPark_id = 1;
}

message CarParkToUpdateRequest {
 int32 device_id = 1;
}
message allCarp{
string status = 1;
}


message carParkResponse{
CarPark carPark =1;
}

就像我说的那样,当我填写正确的请求时,我可以得到回复(除了 allCarParks 方法,但那是一个单独的问题),但是当我尝试做另一个请求时被卡住了。我可以在奇怪的时间发送第二个响应,但就是这样。我只想知道我哪里出错了。任何帮助将非常感激。

【问题讨论】:

    标签: java server client grpc grpc-java


    【解决方案1】:

    在您的服务器端实现中,并不总是调用 onNext() 和 onCompleted(),例如当列表为空或不满足某些条件时,这就是错误。

    【讨论】:

      猜你喜欢
      • 2011-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-02
      • 2019-09-02
      相关资源
      最近更新 更多