Search code examples
c++client-serverrpcgrpc

GRPC error code 12 Client server application C++ [Debug]


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;
}

Solution

  • 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 :)