Improve socket connection style

Previously, a new socket was being opened and closed on every call. Now, there is one socket per client which is used continuously until the connection closes.
This commit is contained in:
ethanglide 2024-07-09 15:04:47 -04:00
parent c9a50d363e
commit 0e3b79dc88
5 changed files with 53 additions and 34 deletions

View File

@ -72,7 +72,7 @@ std::pair<bool, std::string> echo(std::vector<std::string> args)
std::cout << std::endl;
return {true, "Echo Successful"};
return {true, ""};
}
int main(int argc, char **argv)
@ -101,7 +101,7 @@ int main(int argc, char **argv)
client.call("echo", {"Hello", "World"});
client.call("movePlayer", {"1", "5", "5"});
client.call("movePlayer", {"1", "6", "6"});
auto ret = client.call("echol", {"Goodbye", "World"});
auto ret = client.call("echo", {"Goodbye", "World"});
std::cout << "Result: " << ret << std::endl;
}

View File

@ -6,7 +6,6 @@
#include <arpa/inet.h>
#include <stdexcept>
#include <unistd.h>
#include <iostream>
int msgIdCounter = 0;
@ -24,15 +23,7 @@ namespace eRPC
}
this->serverAddress = serverAddress;
}
Client::~Client()
{
closeConnection();
}
void Client::openConnection()
{
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
throw std::runtime_error("Failed to create socket");
@ -44,16 +35,19 @@ namespace eRPC
}
}
void Client::closeConnection()
Client::~Client()
{
Request request(msgIdCounter++, "disconnect", {});
auto serialized = request.serialize();
write(sockfd, serialized.c_str(), serialized.size() + 1);
close(sockfd);
sockfd = -1;
}
std::string Client::call(std::string method, std::vector<std::string> params)
{
Client::openConnection();
Request request(msgIdCounter++, method, params);
auto serialized = request.serialize();
write(sockfd, serialized.c_str(), serialized.size() + 1);
@ -61,8 +55,6 @@ namespace eRPC
char buffer[1024] = {0};
read(sockfd, buffer, 1024);
Client::closeConnection();
Response response(buffer);
if (!response.isOk())

View File

@ -17,9 +17,6 @@ namespace eRPC
private:
int sockfd;
sockaddr_in serverAddress;
void openConnection();
void closeConnection();
};
}

View File

@ -7,6 +7,7 @@
#include <stdexcept>
#include <unistd.h>
#include <memory>
#include <thread>
namespace eRPC
{
@ -50,11 +51,47 @@ namespace eRPC
while (running)
{
auto connfd = accept(sockfd, (sockaddr *)NULL, NULL);
if (connfd < 0)
{
throw std::runtime_error("Failed to accept connection");
}
// Start a new thread to serve the client
std::thread(&Server::serveClient, this, connfd).detach();
}
close(sockfd);
}
void Server::stop()
{
running = false;
}
void Server::bindMethod(std::string method, std::function<std::pair<bool, std::string>(std::vector<std::string>)> callback)
{
methods[method] = callback;
}
void Server::serveClient(int connfd)
{
while (true)
{
char buffer[1024] = {0};
read(connfd, buffer, 1024);
if (read(connfd, buffer, 1024) <= 0)
{
break;
}
// Parse the request
Request request(buffer);
if (request.getMethod() == "disconnect")
{
break;
}
// Call the method if it exists to generate a response
std::unique_ptr<Response> response;
if (methods.find(request.getMethod()) != methods.end())
{
@ -76,20 +113,8 @@ namespace eRPC
auto serialized = response->serialize();
write(connfd, serialized.c_str(), serialized.size() + 1);
close(connfd);
}
close(sockfd);
}
void Server::stop()
{
running = false;
}
void Server::bindMethod(std::string method, std::function<std::pair<bool, std::string>(std::vector<std::string>)> callback)
{
methods[method] = callback;
close(connfd);
}
}

View File

@ -21,7 +21,7 @@ namespace eRPC
~Server();
/**
* Start the server loop.
* Start the server loop. This will block until the server is stopped.
*/
void start();
@ -39,6 +39,11 @@ namespace eRPC
int sockfd;
bool running;
std::unordered_map<std::string, std::function<std::pair<bool, std::string>(std::vector<std::string>)>> methods;
/**
* Keep a socket open and serve a client until they disconnect.
*/
void serveClient(int connfd);
};
}