Refine RPC library

Got multiple remote calls from one client working

Improved error messages

Got function name and arguments sent over as well as return values
This commit is contained in:
ethanglide 2024-07-08 16:15:55 -04:00
parent ed64fb05b1
commit c9a50d363e
7 changed files with 76 additions and 50 deletions

View File

@ -51,6 +51,30 @@ void renderLoop()
}
}
std::pair<bool, std::string> movePlayer(std::vector<std::string> args)
{
int playerId = std::stoi(args[0]);
int x = std::stoi(args[1]);
int y = std::stoi(args[2]);
//gameState.movePlayer(playerId, {x, y});
std::cout << "Player " << playerId << " moved to (" << x << ", " << y << ")" << std::endl;
return {true, "Move Successful"};
}
std::pair<bool, std::string> echo(std::vector<std::string> args)
{
for (auto arg : args)
{
std::cout << arg << " ";
}
std::cout << std::endl;
return {true, "Echo Successful"};
}
int main(int argc, char **argv)
{
if (argc < 4)
@ -66,14 +90,20 @@ int main(int argc, char **argv)
if (mode == "server")
{
eRPC::Server server(port);
server.bindMethod("movePlayer", movePlayer);
server.bindMethod("echo", echo);
server.start();
}
else if (mode == "client")
{
eRPC::Client client(host, port);
client.openConnection();
client.call("Hello from client");
client.closeConnection();
client.call("echo", {"Hello", "World"});
client.call("movePlayer", {"1", "5", "5"});
client.call("movePlayer", {"1", "6", "6"});
auto ret = client.call("echol", {"Goodbye", "World"});
std::cout << "Result: " << ret << std::endl;
}
else
{

View File

@ -8,25 +8,22 @@
#include <unistd.h>
#include <iostream>
int msgIdCounter = 0;
namespace eRPC
{
Client::Client(std::string host, int port) : sockfd(-1), serv_addr()
Client::Client(std::string host, int port) : sockfd(-1), serverAddress()
{
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
throw std::runtime_error("Failed to create socket");
}
sockaddr_in serverAddress;
serverAddress.sin_family = AF_INET;
serverAddress.sin_port = htons(port);
sockaddr_in serv_addr;
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(port);
if (inet_pton(AF_INET, host.c_str(), &serv_addr.sin_addr) <= 0)
if (inet_pton(AF_INET, host.c_str(), &serverAddress.sin_addr) <= 0)
{
throw std::runtime_error("Invalid address");
}
this->serv_addr = serv_addr;
this->serverAddress = serverAddress;
}
Client::~Client()
@ -36,39 +33,43 @@ namespace eRPC
void Client::openConnection()
{
if (sockfd < 0)
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
throw std::runtime_error("Socket not created");
throw std::runtime_error("Failed to create socket");
}
if (connect(sockfd, (sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
if (connect(sockfd, (sockaddr *)&serverAddress, sizeof(serverAddress)) < 0)
{
throw std::runtime_error("Failed to connect to server");
}
std::cout << "Connected to server" << std::endl;
}
void Client::closeConnection()
{
close(sockfd);
sockfd = -1;
}
void Client::call(std::string method)
std::string Client::call(std::string method, std::vector<std::string> params)
{
if (sockfd < 0)
{
throw std::runtime_error("Socket not created");
}
Client::openConnection();
Request request(0, method, {"First argument", "Another argument"});
Request request(msgIdCounter++, method, params);
auto serialized = request.serialize();
write(sockfd, serialized.c_str(), serialized.size() + 1);
char buffer[1024] = {0};
read(sockfd, buffer, 1024);
Client::closeConnection();
Response response(buffer);
std::cout << "Received response:\n" << response.serialize() << std::endl;
if (!response.isOk())
{
throw std::runtime_error(response.getResult());
}
return response.getResult();
}
}

View File

@ -2,6 +2,7 @@
#define ERPC_CLIENT_HPP
#include <string>
#include <vector>
#include <netinet/in.h>
namespace eRPC
@ -11,13 +12,14 @@ namespace eRPC
public:
Client(std::string host, int port);
~Client();
void openConnection();
void closeConnection();
void call(std::string method);
std::string call(std::string method, std::vector<std::string> params);
private:
int sockfd;
sockaddr_in serv_addr;
sockaddr_in serverAddress;
void openConnection();
void closeConnection();
};
}

View File

@ -18,7 +18,7 @@ namespace eRPC
std::getline(iss, line);
if (line != "eRPC 1.0")
{
throw std::runtime_error("Invalid message");
throw std::runtime_error("Invalid Request");
}
std::getline(iss, line);

View File

@ -17,7 +17,7 @@ namespace eRPC
std::getline(iss, line);
if (line != "eRPC 1.0")
{
throw std::runtime_error("Invalid message");
throw std::runtime_error("Invalid Response");
}
std::getline(iss, line);

View File

@ -6,7 +6,6 @@
#include <netinet/in.h>
#include <stdexcept>
#include <unistd.h>
#include <iostream>
#include <memory>
namespace eRPC
@ -32,8 +31,6 @@ namespace eRPC
{
throw std::runtime_error("Failed to listen on socket");
}
std::cout << "Server listening on port " << port << std::endl;
}
Server::~Server()
@ -52,36 +49,32 @@ namespace eRPC
while (running)
{
std::cout << "Waiting for connection" << std::endl;
int connfd = accept(sockfd, (sockaddr *)NULL, NULL);
auto connfd = accept(sockfd, (sockaddr *)NULL, NULL);
char buffer[1024] = {0};
read(connfd, buffer, 1024);
Request request(buffer);
std::cout << "Received request:\n"
<< request.serialize() << std::endl;
std::unique_ptr<Response> response;
if (methods.find(request.getMethod()) != methods.end())
{
std::function<void *()> method = methods[request.getMethod()];
method();
auto method = methods[request.getMethod()];
auto ret = method(request.getParams());
response = std::make_unique<Response>(Response(
request.getMsgid(),
true,
"RESULTS HERE"));
ret.first,
ret.second));
}
else
{
response = std::make_unique<Response>(Response(
request.getMsgid(),
false,
"Method not found"));
"Method \"" + request.getMethod() + "\" not found"));
}
std::string serialized = response->serialize();
auto serialized = response->serialize();
write(connfd, serialized.c_str(), serialized.size() + 1);
close(connfd);
@ -95,7 +88,7 @@ namespace eRPC
running = false;
}
void Server::bindMethod(std::string method, std::function<void *()> callback)
void Server::bindMethod(std::string method, std::function<std::pair<bool, std::string>(std::vector<std::string>)> callback)
{
methods[method] = callback;
}

View File

@ -33,12 +33,12 @@ namespace eRPC
/**
* Bind a method to a callback.
*/
void bindMethod(std::string method, std::function<void *()> callback);
void bindMethod(std::string method, std::function<std::pair<bool, std::string>(std::vector<std::string>)> callback);
private:
int sockfd;
bool running;
std::unordered_map<std::string, std::function<void *()>> methods;
std::unordered_map<std::string, std::function<std::pair<bool, std::string>(std::vector<std::string>)>> methods;
};
}