You can use this example C++ client file as the basis for an RPS client class.

Save this file as rps_client.cpp and put it in the same directory as the code you create in Using Reference Examples with Your System. You will also require an RPS client header file (rps_client.h). Refer to the gRPC Open Source Framework Website for more information about gRPC client and header files.

#include <iostream>
#include <vector>
#include <string>
#include <memory>

#include "rps_client.h"

#include <grpcpp/grpcpp.h>
#include "rps.pb.h"
#include "rps.grpc.pb.h"
#include "bout.h"

using namespace rps_grpc;

bool printGrpcStatusIfNotOk(grpc::Status status)
{
	if (!status.ok())
	{
		std::cout << "ERROR " << status.error_code() << " OCCURRED";
		if (status.error_message() == "")
		{
			std::cout << " (No error message.)" << std::endl
					  << std::endl;
		}
		else
		{
			std::cout << ": " << status.error_message() << std::endl
					  << std::endl;
		}
		return true;
	}
	return false;
}

//////////////////// Constructor/Destructor ////////////////////
RpsClient::RpsClient(std::shared_ptr<grpc::Channel> channel)
	: stub_(RpsService::NewStub(channel)) {}

RpsClient::~RpsClient() {}

//////////////////// Server ////////////////////
int RpsClient::ServerGetStatus(bool &ready, std::string &message)
{
	// Setup
	rps_grpc::ServerGetStatusRequest request;
	rps_grpc::ServerGetStatusResponse response;
	grpc::ClientContext context;

	// Execute RPC
	grpc::Status status = stub_->ServerGetStatus(&context, request, &response);

	// If not okay, print error message to console
	if (printGrpcStatusIfNotOk(status)) return status.error_code();

	ready = response.ready();
	message = response.message();

	return response.status();
};

//////////////////// Core ////////////////////
int RpsClient::Abort()
{
	// Setup
	rps_grpc::AbortRequest request;
	rps_grpc::AbortResponse response;
	grpc::ClientContext context;
	request.mutable_session()->CopyFrom(session_);

	// Execute RPC
	grpc::Status status = stub_->Abort(&context, request, &response);

	// If not okay, print error message to console
	if (printGrpcStatusIfNotOk(status)) return status.error_code();

	return response.status();
};

int RpsClient::Close()
{
	// Setup
	rps_grpc::CloseRequest request;
	rps_grpc::CloseResponse response;
	grpc::ClientContext context;
	request.mutable_session()->CopyFrom(session_);

	// Execute RPC
	grpc::Status status = stub_->Close(&context, request, &response);

	// If not okay, print error message to console
	if (printGrpcStatusIfNotOk(status)) return status.error_code();

	return response.status();
};

int RpsClient::Commit()
{
	// Setup
	rps_grpc::CommitRequest request;
	rps_grpc::CommitResponse response;
	grpc::ClientContext context;
	request.mutable_session()->CopyFrom(session_);

	// Execute RPC
	grpc::Status status = stub_->Commit(&context, request, &response);

	// If not okay, print error message to console
	if (printGrpcStatusIfNotOk(status)) return status.error_code();

	return response.status();
};

int RpsClient::GetStatus(std::vector<int32_t> &logged_statuses, std::string &state, bool &ready, bool &done, 
	std::vector<std::string> &acquisition_tasks, bool &acquisition_tasks_done, std::vector<bool> &overflows)
{
	// Setup
	rps_grpc::GetStatusRequest request;
	rps_grpc::GetStatusResponse response;
	grpc::ClientContext context;
	request.mutable_session()->CopyFrom(session_);

	// Execute RPC
	grpc::Status status = stub_->GetStatus(&context, request, &response);

	// If not okay, print error message to console
	if (printGrpcStatusIfNotOk(status)) return status.error_code();

	// Populate references
	std::vector<int32_t> resp_logged_statuses(response.logged_statuses().begin(), response.logged_statuses().end());
	logged_statuses = resp_logged_statuses;
	state = response.state();
	ready = response.ready();
	// done = response.done();
	// std::vector<std::string> resp_acquisition_tasks(response.acquisition_tasks().begin(), 
       // response.acquisition_tasks().end());
	// acquisition_tasks = resp_acquisition_tasks;
	// acquisition_tasks_done = response.acquisition_tasks_done();
	// std::vector<bool> resp_overflows(response.overflows().begin(), response.overflows().end());
	// overflows = resp_overflows;

	return response.status();
};

int RpsClient::Initialize(std::string session_name, std::string options)
{
	// Setup
	rps_grpc::InitializeRequest request;
	rps_grpc::InitializeResponse response;
	request.set_session_name(session_name);
	request.set_options(options);
	grpc::ClientContext context;

	// Execute RPC
	grpc::Status status = stub_->Initialize(&context, request, &response);

	session_.set_name(response.session().name());
	// If not okay, print error message to console
	if (printGrpcStatusIfNotOk(status)) return status.error_code();

	return response.status();
};

int RpsClient::Start()
{
	// Setup
	rps_grpc::StartRequest request;
	rps_grpc::StartResponse response;
	grpc::ClientContext context;
	request.mutable_session()->CopyFrom(session_);

	// Execute RPC
	grpc::Status status = stub_->Start(&context, request, &response);

	// If not okay, print error message to console
	if (printGrpcStatusIfNotOk(status)) return status.error_code();

	return response.status();
};

// int RpsClient::Stop()
// {
// 	// Setup
// 	rps_grpc::StopRequest request;
// 	rps_grpc::StopResponse response;
// 	grpc::ClientContext context;
// 	request.mutable_session()->CopyFrom(session_);

// 	// Execute RPC
// 	grpc::Status status = stub_->Stop(&context, request, &response);

// 	// If not okay, print error message to console
// 	if (printGrpcStatusIfNotOk(status)) return status.error_code();

// 	return response.status();
// };

//////////////////// Acquisition ////////////////////
int RpsClient::AcquisitionFetchIQ(std::string task_name, rps_grpc::AcquisitionFetchIQResponse &response)
{
	// Setup
	rps_grpc::AcquisitionFetchIQRequest request;
	grpc::ClientContext context;
	request.mutable_session()->CopyFrom(session_);
	request.set_task_name(task_name);

	// Execute RPC
	grpc::Status status = stub_->AcquisitionFetchIQ(&context, request, &response);

	// If not okay, print error message to console
	if (printGrpcStatusIfNotOk(status)) return status.error_code();

	return response.status();
};

int RpsClient::AcquisitionGetStatus(std::string task_name, rps_grpc::AcquisitionGetStatusResponse &response)
{
	// Setup
	rps_grpc::AcquisitionGetStatusRequest request;
	request.mutable_session()->CopyFrom(session_);
	request.set_task_name(task_name);
	grpc::ClientContext context;

	// Execute RPC
	grpc::Status status = stub_->AcquisitionGetStatus(&context, request, &response);

	// If not okay, print error message to console
	if (printGrpcStatusIfNotOk(status)) return status.error_code();

	return response.status();
};

int RpsClient::AcquisitionSetBandwidth(std::string task_name, int64_t bandwidth_hz)
{
	// Setup
	rps_grpc::AcquisitionSetBandwidthRequest request;
	rps_grpc::AcquisitionSetBandwidthResponse response;
	grpc::ClientContext context;
	request.mutable_session()->CopyFrom(session_);
	request.set_task_name(task_name);
	request.set_bandwidth_hz(bandwidth_hz);

	// Execute RPC
	grpc::Status status = stub_->AcquisitionSetBandwidth(&context, request, &response);

	// If not okay, print error message to console
	if (printGrpcStatusIfNotOk(status)) return status.error_code();

	return response.status();
};

int RpsClient::AcquisitionSetFetchSize(std::string task_name, uint64_t fetch_size)
{
	// Setup
	rps_grpc::AcquisitionSetFetchSizeRequest request;
	rps_grpc::AcquisitionSetFetchSizeResponse response;
	grpc::ClientContext context;
	request.mutable_session()->CopyFrom(session_);
	request.set_task_name(task_name);
	request.set_fetch_size(fetch_size);

	// Execute RPC
	grpc::Status status = stub_->AcquisitionSetFetchSize(&context, request, &response);

	// If not okay, print error message to console
	if (printGrpcStatusIfNotOk(status)) return status.error_code();

	return response.status();
};

int RpsClient::AcquisitionSetFrequency(std::string task_name, double center_frequency_hz)
{
	// Setup
	rps_grpc::AcquisitionSetFrequencyRequest request;
	rps_grpc::AcquisitionSetFrequencyResponse response;
	grpc::ClientContext context;
	request.mutable_session()->CopyFrom(session_);
	request.set_task_name(task_name);
	request.set_center_frequency_hz(center_frequency_hz);

	// Execute RPC
	grpc::Status status = stub_->AcquisitionSetFrequency(&context, request, &response);

	// If not okay, print error message to console
	if (printGrpcStatusIfNotOk(status)) return status.error_code();

	return response.status();
};

int RpsClient::AcquisitionSetFrequencies(std::string task_name, std::vector<double> center_frequency_hz)
{
	// Setup
	rps_grpc::AcquisitionSetFrequenciesRequest request;
	rps_grpc::AcquisitionSetFrequenciesResponse response;
	grpc::ClientContext context;
	request.mutable_session()->CopyFrom(session_);
	request.set_task_name(task_name);
	int index = 0;
	for (auto frequency : center_frequency_hz)
	{
		request.set_center_frequencies_hz(index, frequency);
		index++;
	}

	// Execute RPC
	grpc::Status status = stub_->AcquisitionSetFrequencies(&context, request, &response);

	// If not okay, print error message to console
	if (printGrpcStatusIfNotOk(status)) return status.error_code();

	return response.status();
};

int RpsClient::AcquisitionSetLO(std::string task_name, RpsType::LOType lo_type, std::string data)
{
	// Setup
	rps_grpc::AcquisitionSetLORequest request;
	rps_grpc::AcquisitionSetLOResponse response;
	grpc::ClientContext context;
	request.mutable_session()->CopyFrom(session_);
	request.set_task_name(task_name);
	switch(lo_type)
	{
		case RpsType::LOType::UNSPECIFIED:
			request.set_lo_type(rps_grpc::LOType::LO_TYPE_UNSPECIFIED);
			break;
		case RpsType::LOType::NONE:
			request.set_lo_type(rps_grpc::LOType::LO_TYPE_NONE);
			break;
		case RpsType::LOType::CUSTOM:
			request.set_lo_type(rps_grpc::LOType::LO_TYPE_CUSTOM);
			break;
		case RpsType::LOType::DAISY_CHAIN:
			request.set_lo_type(rps_grpc::LOType::LO_TYPE_DAISY_CHAIN);
			break;
		case RpsType::LOType::STAR:
			request.set_lo_type(rps_grpc::LOType::LO_TYPE_STAR);
			break;
		case RpsType::LOType::STAR_CALIBRATED:
			request.set_lo_type(rps_grpc::LOType::LO_TYPE_STAR_CALIBRATED);
			break;
		default:
			Bout::info("Invalid LO type, set to unspecified.");
			request.set_lo_type(rps_grpc::LOType::LO_TYPE_UNSPECIFIED);
			break;
	}
	request.set_data(data);

	// Execute RPC
	grpc::Status status = stub_->AcquisitionSetLO(&context, request, &response);

	// If not okay, print error message to console
	if (printGrpcStatusIfNotOk(status)) return status.error_code();

	return response.status();
};

int RpsClient::AcquisitionSetPhaseCal(std::string task_name, RpsType::PhaseCalType phase_cal_type, std::string data)
{
	// Setup
	rps_grpc::AcquisitionSetPhaseCalRequest request;
	rps_grpc::AcquisitionSetPhaseCalResponse response;
	grpc::ClientContext context;
	request.mutable_session()->CopyFrom(session_);
	request.set_task_name(task_name);
	switch(phase_cal_type)
	{
		case RpsType::PhaseCalType::UNSPECIFIED:
			request.set_phase_cal_type(rps_grpc::PhaseCalType::PHASE_CAL_TYPE_UNSPECIFIED);
			break;
		case RpsType::PhaseCalType::NONE:
			request.set_phase_cal_type(rps_grpc::PhaseCalType::PHASE_CAL_TYPE_NONE);
			break;
		case RpsType::PhaseCalType::COHERENT:
			request.set_phase_cal_type(rps_grpc::PhaseCalType::PHASE_CAL_TYPE_COHERENT);
			break;
		case RpsType::PhaseCalType::ALIGNED:
			request.set_phase_cal_type(rps_grpc::PhaseCalType::PHASE_CAL_TYPE_ALIGNED);
			break;
	}
	request.set_data(data);

	// Execute RPC
	grpc::Status status = stub_->AcquisitionSetPhaseCal(&context, request, &response);

	// If not okay, print error message to console
	if (printGrpcStatusIfNotOk(status)) return status.error_code();

	return response.status();
};

int RpsClient::AcquisitionSetReferenceClock(std::string task_name, std::string reference_clock)
{
	// Setup
	rps_grpc::AcquisitionSetReferenceClockRequest request;
	rps_grpc::AcquisitionSetReferenceClockResponse response;
	grpc::ClientContext context;
	request.mutable_session()->CopyFrom(session_);
	request.set_task_name(task_name);
	request.set_reference_clock(reference_clock);

	// Execute RPC
	grpc::Status status = stub_->AcquisitionSetReferenceClock(&context, request, &response);

	// If not okay, print error message to console
	if (printGrpcStatusIfNotOk(status)) return status.error_code();

	return response.status();
};

int RpsClient::AcquisitionSetReferenceLevel(std::string task_name, double reference_level)
{
	// Setup
	rps_grpc::AcquisitionSetReferenceLevelRequest request;
	rps_grpc::AcquisitionSetReferenceLevelResponse response;
	grpc::ClientContext context;
	request.mutable_session()->CopyFrom(session_);
	request.set_task_name(task_name);
	request.set_reference_level(reference_level);

	// Execute RPC
	grpc::Status status = stub_->AcquisitionSetReferenceLevel(&context, request, &response);

	// If not okay, print error message to console
	if (printGrpcStatusIfNotOk(status)) return status.error_code();

	return response.status();
};

int RpsClient::AcquisitionSetSampleRate(std::string task_name, int64_t sample_rate)
{
	// Setup
	rps_grpc::AcquisitionSetSampleRateRequest request;
	rps_grpc::AcquisitionSetSampleRateResponse response;
	grpc::ClientContext context;
	request.mutable_session()->CopyFrom(session_);
	request.set_task_name(task_name);
	request.set_sample_rate(sample_rate);

	// Execute RPC
	grpc::Status status = stub_->AcquisitionSetSampleRate(&context, request, &response);

	// If not okay, print error message to console
	if (printGrpcStatusIfNotOk(status)) return status.error_code();

	return response.status();
};

int RpsClient::AcquisitionCreateTask(std::string task_name, std::string instrument_names, std::string option_string)
{
	// Setup
	rps_grpc::AcquisitionCreateTaskRequest request;
	rps_grpc::AcquisitionCreateTaskResponse response;
	grpc::ClientContext context;
	request.mutable_session()->CopyFrom(session_);
	request.set_task_name(task_name);
	request.set_instrument_names(instrument_names);
	request.set_options(option_string);

	// Execute RPC
	grpc::Status status = stub_->AcquisitionCreateTask(&context, request, &response);
	// If not okay, print error message to console
	if (printGrpcStatusIfNotOk(status)) return status.error_code();

	return 0;
};

//////////////////// Sync ////////////////////
int RpsClient::SynchronizationCreateConfiguration(RpsType::SynchronizationType sync_config_type)
{
	// Setup
	rps_grpc::SynchronizationCreateConfigurationRequest request;
	rps_grpc::SynchronizationCreateConfigurationResponse response;
	grpc::ClientContext context;
	request.mutable_session()->CopyFrom(session_);
	request.set_sync_type(static_cast<SynchronizationType>(sync_config_type));

	// Execute RPC
	grpc::Status status = stub_->SynchronizationCreateConfiguration(&context, request, &response);

	// If not okay, print error message to console
	if (printGrpcStatusIfNotOk(status)) return status.error_code();

	return response.status();
}

int RpsClient::SynchronizationSetMasterTask(std::string task_name)
{
	// Setup
	rps_grpc::SynchronizationSetMasterTaskRequest request;
	rps_grpc::SynchronizationSetMasterTaskResponse response;
	grpc::ClientContext context;
	request.mutable_session()->CopyFrom(session_);
	request.set_task_name(task_name);

	// Execute RPC
	grpc::Status status = stub_->SynchronizationSetMasterTask(&context, request, &response);

	// If not okay, print error message to console
	if (printGrpcStatusIfNotOk(status)) return status.error_code();

	return response.status();
}

int RpsClient::SynchronizationSetSlaveTask(std::string task_name)
{
	// Setup
	rps_grpc::SynchronizationSetSlaveTaskRequest request;
	rps_grpc::SynchronizationSetSlaveTaskResponse response;
	grpc::ClientContext context;
	request.mutable_session()->CopyFrom(session_);
	request.set_task_name(task_name);
	// Execute RPC
	grpc::Status status = stub_->SynchronizationSetSlaveTask(&context, request, &response);

	// If not okay, print error message to console
	if (printGrpcStatusIfNotOk(status)) return status.error_code();

	return response.status();
}

//////////////////// Stream ////////////////////
int RpsClient::StreamCreateConfiguration(std::string configuration_name, StreamType configuration_type, Unit length_unit, int64_t length)
{
	// setup
	rps_grpc::StreamCreateConfigurationRequest request;
	rps_grpc::StreamCreateConfigurationResponse response;
	grpc::ClientContext context;
	request.mutable_session()->CopyFrom(session_);
	request.set_configuration_name(configuration_name);
	request.set_stream_type(configuration_type);
	request.set_length_unit(length_unit);
	request.set_length(length);
	// Execute RPC
	grpc::Status status = stub_->StreamCreateConfiguration(&context, request, &response);

	// If not okay print error message to console
	if (printGrpcStatusIfNotOk(status)) return status.error_code();

	return response.status();
};

int RpsClient::StreamSetSourceEndpoint(std::string configuration_name, rps_grpc::StreamSourceEndpoint endpoint, std::string data)
{
	// setup
	rps_grpc::StreamSetSourceEndpointRequest request;
	rps_grpc::StreamSetSourceEndpointResponse response;
	grpc::ClientContext context;
	request.mutable_session()->CopyFrom(session_);
	request.set_configuration_name(configuration_name);
	request.set_endpoint(endpoint);
	request.set_data(data);

	// Execute RPC
	grpc::Status status = stub_->StreamSetSourceEndpoint(&context, request, &response);

	// If not okay print error message to console
	if (printGrpcStatusIfNotOk(status)) return status.error_code();

	return response.status();
};

int RpsClient::StreamSetDestinationEndpoint(std::string configuration_name, rps_grpc::StreamDestinationEndpoint endpoint, std::string data)
{
	// setup
	rps_grpc::StreamSetDestinationEndpointRequest request;
	rps_grpc::StreamSetDestinationEndpointResponse response;
	grpc::ClientContext context;
	request.mutable_session()->CopyFrom(session_);
	request.set_configuration_name(configuration_name);
	request.set_endpoint(endpoint);
	request.set_data(data);

	// Execute RPC
	grpc::Status status = stub_->StreamSetDestinationEndpoint(&context, request, &response);

	// If not okay print error message to console
	if (printGrpcStatusIfNotOk(status)) return status.error_code();

	return response.status();
};

int RpsClient::StreamGetStatus(std::string configuration_name, int32_t& stream_status, std::vector<std::string>& task_names, std::vector<std::string>& instr_names, std::vector<uint64_t>& samples_to_stream, std::vector<uint64_t>& samples_streamed, std::vector<bool>& overflow, bool& any_overflow, bool& done)
{
	// setup
	rps_grpc::StreamGetStatusRequest request;
	rps_grpc::StreamGetStatusResponse response;
	grpc::ClientContext context;
	request.mutable_session()->CopyFrom(session_);
	request.set_configuration_name(configuration_name);

	// Execute RPC
	grpc::Status status = stub_->StreamGetStatus(&context, request, &response);
	
	// If not okay print error message to console
	if (printGrpcStatusIfNotOk(status)) return status.error_code();

	stream_status = response.stream_status();
	std::vector<std::string> tasks(response.task_name().begin(), response.task_name().end());
	task_names = tasks;
	std::vector<std::string> instruments(response.instrument_name().begin(), response.instrument_name().end());
	instr_names = instruments;
	std::vector<uint64_t> samples_to_stream_vec(response.samples_to_stream().begin(), response.samples_to_stream().end());
	samples_to_stream = samples_to_stream_vec;
	std::vector<uint64_t> samples_streamed_vec(response.samples_streamed().begin(), response.samples_streamed().end());
	samples_streamed = samples_streamed_vec;
	std::vector<bool> overflow_vec(response.overflow().begin(), response.overflow().end());
	overflow = overflow_vec;
	any_overflow = response.any_overflow();
	done = response.done();

	return response.status();
};

//////////////////// Advanced ////////////////////
int RpsClient::GetErrorString(int32_t error_code, std::string &error_string)
{
	// Setup
	rps_grpc::GetErrorStringRequest request;
	rps_grpc::GetErrorStringResponse response;
	grpc::ClientContext context;

	request.set_error_code(error_code);

	// Execute RPC
	grpc::Status status = stub_->GetErrorString(&context, request, &response);

	// If not okay, print error message to console
	if (printGrpcStatusIfNotOk(status)) return status.error_code();

	error_string = response.error_string();
	// Will call into mms to get error string

	return response.status();
};

int RpsClient::Message(std::string name, std::string& data)
{
	// Setup
	rps_grpc::MessageRequest request;
	rps_grpc::MessageResponse response;
	grpc::ClientContext context;
	request.set_name(name);
	if(data != "")
		request.set_data(data);

	// Execute RPC
	grpc::Status status = stub_->Message(&context, request, &response);

	data = response.data();

	// If not okay, print error message to console
	if (printGrpcStatusIfNotOk(status)) return status.error_code();

	return status.error_code();
};