I need to create a client server application in C++ using gRPC. I referred to the following tutorial and the example on gRPC to make a client server application which looks very similar to the helloworld example (grpc/examples/cpp/helloworld/
) in the repository. However, when I run the server side (manager.cc
), I get a message saying Error code 12: RPC failed
. Please let me know where I am going wrong:
manager.cc(similar to greeter_server.cc):
#include<stdio.h>
#include<iostream>
#include <memory>
#include <string>
#include <grpcpp/grpcpp.h>
#include "nodes.grpc.pb.h"
#include<map>
#define MAX_NODES 20
using namespace std;
using grpc::Server;
using grpc::ServerBuilder;
using grpc::ServerContext;
using grpc::Status;
using nodes::joinrequest;
using nodes::nodejoin;
using nodes::serverresponse;
struct track
{
int nodes_having_it[MAX_NODES];
int last_serviced_by;
int tot_nodes;
};
#define MAX_NO_OF_NODES 15
static map<int,int> map_key_node;//Primary
static map<int, struct track> track_service;//Keep track of replicated nodes that have the key
static map<int, int> version_map;
list <int> nodes_joined;
struct NodeDS{
int nodeid;
int pred;
int succ;
int version;
static map<int,int> data_stored;//storage
};
class nodejoining final: public nodejoin::Service
{
Status joinCM(ServerContext* context, joinrequest* request,serverresponse* reply_CM)
{
cout << "called";
int node_id = request -> id();
nodes_joined.push_back(node_id);
//reply_CM.set_stat("done");
cout << "OK";
return Status::OK;
}
};
void Nodeserver()
{
std::string server_address("0.0.0.0:50051"); // As of now to test with a single node, have to figure out a way to give different addressed to different nodes.
nodejoining service;
ServerBuilder builder;
builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
builder.RegisterService(&service);
std::unique_ptr<Server> server(builder.BuildAndStart());
std::cout << "Server listening on " << server_address << std::endl;
server->Wait();
}
int main()
{
Nodeserver();
std::hash<string> hashvalue;
string client_id = "Haha"; //As of now --- to be obtained from client later
long nodeid_hash = hashvalue(client_id);
cout << nodeid_hash << "\n";
int data = 100;
return 0;
}
node.cc(similar to greeter_client.cc):
#include<stdio.h>
#include<iostream>
#include <memory>
#include <string>
#include <grpcpp/grpcpp.h>
#include "nodes.grpc.pb.h"
#include<map>
#define MAX_NODES 20
using namespace std;
using grpc::Channel;
using grpc::ClientContext;
using grpc::Status;
using nodes::joinrequest;
using nodes::nodejoin;
using nodes::serverresponse;
class Node_init
{
public:
Node_init(std::shared_ptr<Channel> channel): stub_(nodejoin::NewStub(channel)) {}
std::string joinCM(const int& n_id)
{
joinrequest request_CM;
request_CM.set_id(n_id);
cout << "1" << "\n";
serverresponse reply_CM;
ClientContext context;
cout << "\n" << "2";
Status status = stub_->joinCM(&context, request_CM, &reply_CM);
cout << "\n" << "3";
if(status.ok())
{
cout<<"\n I have joined you";
return "Success";
}
else
{ std::cout << status.error_code() << ": " << status.error_message() << std::endl;
return "Failed";
}
}
private:
std::unique_ptr<nodejoin::Stub> stub_;
};
int main(int argc, char** argv)
{
Node_init nj(grpc::CreateChannel("localhost:50051",grpc::InsecureChannelCredentials()));
std::string reply = nj.joinCM(2);
std::cout << "\n" << reply;
}
nodes.proto (similar to helloworld.proto in grpc/examples/protos/ ):
syntax = "proto3";
package nodes;
service nodejoin
{
rpc joinCM (joinrequest) returns (serverresponse) {}
}
message joinrequest
{
int32 id = 1;
}
message serverresponse
{
string stat = 1;
}
There is a const missing in your definition of joinCM
Status joinCM(ServerContext* context, joinrequest* request,serverresponse* reply_CM)
It should be
Status joinCM(ServerContext* context, const joinrequest* request,serverresponse* reply_CM)
instead. The compiler indicates this through a 'hides overloaded virtual function' warning :)