private void forwardToService(
      SocketRpcProtos.Request rpcRequest,
      RpcCallback<Message> callback,
      Service service,
      RpcController socketController)
      throws RpcException {
    // Get matching method
    MethodDescriptor method = getMethod(rpcRequest, service.getDescriptorForType());

    // Create request for method
    Message request = getRequestProto(rpcRequest, service.getRequestPrototype(method));

    // Call method
    try {
      service.callMethod(method, socketController, request, callback);
    } catch (RuntimeException e) {
      throw new RpcException(
          ErrorReason.RPC_ERROR, "Error running method " + method.getFullName(), e);
    }
  }
  private Response forwardToBlockingService(Request rpcRequest, BlockingService blockingService)
      throws RpcException {
    // Get matching method
    MethodDescriptor method = getMethod(rpcRequest, blockingService.getDescriptorForType());

    // Create request for method
    Message request = getRequestProto(rpcRequest, blockingService.getRequestPrototype(method));

    // Call method
    SocketRpcController socketController = new SocketRpcController();
    try {
      Message response = blockingService.callBlockingMethod(method, socketController, request);
      return createRpcResponse(response, true, socketController);
    } catch (ServiceException e) {
      throw new RpcException(ErrorReason.RPC_FAILED, e.getMessage(), e);
    } catch (RuntimeException e) {
      throw new RpcException(
          ErrorReason.RPC_ERROR, "Error running method " + method.getFullName(), e);
    }
  }