refactor RpcService class
This commit is contained in:
parent
43b5f2ffb6
commit
82cd11a4af
2 changed files with 148 additions and 154 deletions
random-sensor-ldmc
115
random-sensor-ldmc/rpc_service.hpp
Normal file
115
random-sensor-ldmc/rpc_service.hpp
Normal file
|
@ -0,0 +1,115 @@
|
|||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <unistd.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/socket.h>
|
||||
#include <cstring>
|
||||
#include <map>
|
||||
#include <functional>
|
||||
|
||||
template < typename T_RpcTag >
|
||||
struct RpcService {
|
||||
private:
|
||||
uint32_t port;
|
||||
std::map< T_RpcTag, std::function<void( char const * input, size_t input_len, int client_sock )> > handler;
|
||||
|
||||
public:
|
||||
RpcService(uint32_t port) :port(port)
|
||||
{}
|
||||
|
||||
template < typename F, typename Request, typename Response >
|
||||
void register_handler(T_RpcTag tag, std::function<F(Request const&, Response&)> f) {
|
||||
handler.emplace(
|
||||
tag,
|
||||
std::function([f]( char const * request_buffer, size_t len, int client_sock ) {
|
||||
Request * request = (Request*) (request_buffer + sizeof(T_RpcTag));
|
||||
Response response;
|
||||
f( *request, response );
|
||||
send(client_sock, (void const*)&response, sizeof(response), 0);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
void handle_client(int client_sock) {
|
||||
char request_buffer[1024];
|
||||
ssize_t bytes_received;
|
||||
|
||||
// Receive data from client
|
||||
bytes_received = recv(client_sock, request_buffer, sizeof(request_buffer), 0);
|
||||
if (bytes_received == -1) {
|
||||
std::cerr << "Failed to receive data" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
printf("received %lu bytes:\n", bytes_received);
|
||||
for( size_t i = 0; i < bytes_received;)
|
||||
{
|
||||
printf("%4lx : ", i);
|
||||
for( size_t col = 0; col < 8; ++col ) {
|
||||
printf("%2x ", request_buffer[i++]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
if (bytes_received >= sizeof(T_RpcTag) ) {
|
||||
T_RpcTag * tag = (T_RpcTag*) request_buffer;
|
||||
if( handler.contains(*tag) ){
|
||||
(handler[*tag])( request_buffer, bytes_received, client_sock );
|
||||
} else {
|
||||
std::string response("invalid RPC");
|
||||
send(client_sock, response.c_str(), response.length(), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int run() {
|
||||
int server_sock, client_sock;
|
||||
struct sockaddr_in server_addr, client_addr;
|
||||
socklen_t addr_len = sizeof(client_addr);
|
||||
|
||||
// Create socket
|
||||
server_sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (server_sock == -1) {
|
||||
std::cerr << "Failed to create socket" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Set up server address
|
||||
server_addr.sin_family = AF_INET;
|
||||
server_addr.sin_addr.s_addr = INADDR_ANY;
|
||||
server_addr.sin_port = htons(port);
|
||||
|
||||
// Bind socket to the address and port
|
||||
if (bind(server_sock, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) {
|
||||
std::cerr << "Failed to bind socket" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Listen for incoming connections
|
||||
if (listen(server_sock, 3) == -1) {
|
||||
std::cerr << "Failed to listen on socket" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
std::cout << "Server listening on port " << port << "..." << std::endl;
|
||||
|
||||
// Accept and handle client connections
|
||||
while (true) {
|
||||
client_sock = accept(server_sock, (struct sockaddr*)&client_addr, &addr_len);
|
||||
if (client_sock == -1) {
|
||||
std::cerr << "Failed to accept connection" << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
std::cout << "Client connected!" << std::endl;
|
||||
handle_client(client_sock);
|
||||
|
||||
// Close the client socket after handling the request
|
||||
close(client_sock);
|
||||
}
|
||||
|
||||
// Close the server socket
|
||||
close(server_sock);
|
||||
}
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue