mirror of
https://github.com/haiwen/libsearpc.git
synced 2025-08-31 20:37:07 +00:00
Multiple services support in searpc server.
This commit is contained in:
@@ -77,7 +77,7 @@ static void
|
||||
strlen_callback(void *vresult, void *user_data, GError *error)
|
||||
{
|
||||
const char *str = user_data;
|
||||
int len = (int)(long)vresult;
|
||||
int len = *((int *)vresult);
|
||||
|
||||
g_assert (strcmp(str, "user data") == 0);
|
||||
printf("the length of string 'hello searpc' is %d.\n", len);
|
||||
|
@@ -29,13 +29,15 @@ static void
|
||||
start_rpc_service(void)
|
||||
{
|
||||
searpc_server_init();
|
||||
searpc_create_service("searpc-demo");
|
||||
|
||||
/* The first parameter is the implementation function.
|
||||
* The second parameter is the name of the rpc function the
|
||||
* client would call.
|
||||
* The third parameter is the signature.
|
||||
*/
|
||||
searpc_server_register_function(searpc_strlen,
|
||||
searpc_server_register_function("searpc-demo",
|
||||
searpc_strlen,
|
||||
"searpc_strlen",
|
||||
searpc_signature_int__string());
|
||||
}
|
||||
@@ -106,7 +108,7 @@ main(int argc, char *argv[])
|
||||
gsize ret_len;
|
||||
int fcall_len = ntohs(pac->length);
|
||||
/* Execute the RPC function */
|
||||
char *res = searpc_server_call_function (pac->data, fcall_len,
|
||||
char *res = searpc_server_call_function ("searpc-demo", pac->data, fcall_len,
|
||||
&ret_len, &error);
|
||||
|
||||
pac_ret = (packet *)buf;
|
||||
|
@@ -27,6 +27,13 @@ typedef struct FuncItem {
|
||||
MarshalItem *marshal;
|
||||
} FuncItem;
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
GHashTable *func_table;
|
||||
} SearpcService;
|
||||
|
||||
static GHashTable *marshal_table;
|
||||
static GHashTable *service_table;
|
||||
|
||||
static void
|
||||
func_item_free (FuncItem *item)
|
||||
@@ -42,9 +49,42 @@ marshal_item_free (MarshalItem *item)
|
||||
g_free (item);
|
||||
}
|
||||
|
||||
static GHashTable *marshal_table;
|
||||
static GHashTable *func_table;
|
||||
int
|
||||
searpc_create_service (const char *svc_name)
|
||||
{
|
||||
SearpcService *service;
|
||||
|
||||
if (!svc_name)
|
||||
return -1;
|
||||
|
||||
if (g_hash_table_lookup (service_table, svc_name) != NULL)
|
||||
return 0;
|
||||
|
||||
service = g_new0 (SearpcService, 1);
|
||||
service->name = g_strdup(svc_name);
|
||||
service->func_table = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
NULL, (GDestroyNotify)func_item_free);
|
||||
|
||||
g_hash_table_insert (service_table, service->name, service);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
service_free (SearpcService *service)
|
||||
{
|
||||
g_free (service->name);
|
||||
g_hash_table_destroy (service->func_table);
|
||||
g_free (service);
|
||||
}
|
||||
|
||||
void
|
||||
searpc_remove_service (const char *svc_name)
|
||||
{
|
||||
if (!svc_name)
|
||||
return;
|
||||
g_hash_table_remove (service_table, svc_name);
|
||||
}
|
||||
|
||||
/* Marshal functions */
|
||||
static inline void
|
||||
@@ -124,10 +164,10 @@ marshal_set_ret_common (JsonObject *object, gsize *len, GError *error)
|
||||
void
|
||||
searpc_server_init ()
|
||||
{
|
||||
func_table = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
NULL, (GDestroyNotify)func_item_free);
|
||||
marshal_table = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
NULL, (GDestroyNotify)marshal_item_free);
|
||||
service_table = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
NULL, (GDestroyNotify)service_free);
|
||||
|
||||
/* register buildin marshal functions */
|
||||
register_marshals(marshal_table);
|
||||
@@ -136,7 +176,7 @@ searpc_server_init ()
|
||||
void
|
||||
searpc_server_final()
|
||||
{
|
||||
g_hash_table_destroy (func_table);
|
||||
g_hash_table_destroy (service_table);
|
||||
g_hash_table_destroy (marshal_table);
|
||||
}
|
||||
|
||||
@@ -162,12 +202,18 @@ searpc_server_register_marshal (gchar *signature, SearpcMarshalFunc marshal)
|
||||
}
|
||||
|
||||
gboolean
|
||||
searpc_server_register_function (void *func, const gchar *fname, gchar *signature)
|
||||
searpc_server_register_function (const char *svc_name,
|
||||
void *func, const gchar *fname, gchar *signature)
|
||||
{
|
||||
SearpcService *service;
|
||||
FuncItem *item;
|
||||
MarshalItem *mitem;
|
||||
|
||||
g_assert (func != NULL && fname != NULL && signature != NULL);
|
||||
g_assert (svc_name != NULL && func != NULL && fname != NULL && signature != NULL);
|
||||
|
||||
service = g_hash_table_lookup (service_table, svc_name);
|
||||
if (!service)
|
||||
return FALSE;
|
||||
|
||||
mitem = g_hash_table_lookup (marshal_table, signature);
|
||||
if (!mitem) {
|
||||
@@ -180,7 +226,7 @@ searpc_server_register_function (void *func, const gchar *fname, gchar *signatur
|
||||
item->fname = g_strdup(fname);
|
||||
item->func = func;
|
||||
|
||||
g_hash_table_insert (func_table, (gpointer)item->fname, item);
|
||||
g_hash_table_insert (service->func_table, (gpointer)item->fname, item);
|
||||
|
||||
g_free (signature);
|
||||
return TRUE;
|
||||
@@ -188,8 +234,10 @@ searpc_server_register_function (void *func, const gchar *fname, gchar *signatur
|
||||
|
||||
/* Called by RPC transport. */
|
||||
gchar*
|
||||
searpc_server_call_function (gchar *func, gsize len, gsize *ret_len, GError **error)
|
||||
searpc_server_call_function (const char *svc_name,
|
||||
gchar *func, gsize len, gsize *ret_len, GError **error)
|
||||
{
|
||||
SearpcService *service;
|
||||
JsonParser *parser;
|
||||
JsonNode *root;
|
||||
JsonArray *array;
|
||||
@@ -200,6 +248,13 @@ searpc_server_call_function (gchar *func, gsize len, gsize *ret_len, GError **er
|
||||
#endif
|
||||
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||
|
||||
service = g_hash_table_lookup (service_table, svc_name);
|
||||
if (!service) {
|
||||
g_warning ("[SeaRPC] cannot find service %s.\n", svc_name);
|
||||
g_set_error (error, 0, 501, "cannot find service %s.", svc_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
parser = json_parser_new ();
|
||||
|
||||
@@ -213,7 +268,7 @@ searpc_server_call_function (gchar *func, gsize len, gsize *ret_len, GError **er
|
||||
array = json_node_get_array (root);
|
||||
|
||||
const char *fname = json_array_get_string_element(array, 0);
|
||||
FuncItem *fitem = g_hash_table_lookup(func_table, fname);
|
||||
FuncItem *fitem = g_hash_table_lookup(service->func_table, fname);
|
||||
if (!fitem) {
|
||||
g_warning ("[SeaRPC] cannot find function %s.\n", fname);
|
||||
g_set_error (error, 0, 500, "cannot find function %s.", fname);
|
||||
|
@@ -22,6 +22,23 @@ void searpc_server_init ();
|
||||
*/
|
||||
void searpc_server_final ();
|
||||
|
||||
/**
|
||||
* searpc_create_service:
|
||||
*
|
||||
* Create a new service. Service is a set of functions.
|
||||
* The new service will be registered to the server.
|
||||
*
|
||||
* @svc_name: Service name.
|
||||
*/
|
||||
int searpc_create_service (const char *svc_name);
|
||||
|
||||
/**
|
||||
* searpc_remove_service:
|
||||
*
|
||||
* Remove the service from the server.
|
||||
*/
|
||||
void searpc_remove_service (const char *svc_name);
|
||||
|
||||
/**
|
||||
* searpc_server_register_marshal:
|
||||
*
|
||||
@@ -36,26 +53,29 @@ gboolean searpc_server_register_marshal (gchar *signature,
|
||||
/**
|
||||
* searpc_server_register_function:
|
||||
*
|
||||
* Register a rpc function with given signature.
|
||||
*
|
||||
* Register a rpc function with given signature to a service.
|
||||
*
|
||||
* @signature: the signature of the function, register_function() will take
|
||||
* owner of this string.
|
||||
*/
|
||||
gboolean searpc_server_register_function (void* func,
|
||||
gboolean searpc_server_register_function (const char *service,
|
||||
void* func,
|
||||
const gchar *fname,
|
||||
gchar *signature);
|
||||
|
||||
/**
|
||||
* searpc_server_call_function:
|
||||
* @service: service name.
|
||||
* @func: the serialized representation of the function to call.
|
||||
* @len: length of @func.
|
||||
* @ret_len: the length of the returned string.
|
||||
*
|
||||
* Call a registered function @func.
|
||||
* Call a registered function @func of a service.
|
||||
*
|
||||
* Returns the serialized representatio of the returned value.
|
||||
*/
|
||||
gchar *searpc_server_call_function (gchar *func, gsize len, gsize *ret_len,
|
||||
gchar *searpc_server_call_function (const char *service,
|
||||
gchar *func, gsize len, gsize *ret_len,
|
||||
GError **error);
|
||||
|
||||
/**
|
||||
|
@@ -172,7 +172,7 @@ void test_simple_call (void *fixture, const void *data)
|
||||
|
||||
fcall = searpc_client_fcall__string_int ("get_substring", "hello", 2,
|
||||
&fcall_len);
|
||||
fret = searpc_server_call_function (fcall, fcall_len, &ret_len, &error);
|
||||
fret = searpc_server_call_function ("test", fcall, fcall_len, &ret_len, &error);
|
||||
g_assert (error == NULL);
|
||||
result = searpc_client_fret__string (fret, ret_len, &error);
|
||||
g_assert (strcmp(result, "he") == 0);
|
||||
@@ -184,7 +184,7 @@ void test_simple_call (void *fixture, const void *data)
|
||||
result = NULL;
|
||||
fcall = searpc_client_fcall__string_int ("get_substring", "hello", 7,
|
||||
&fcall_len);
|
||||
fret = searpc_server_call_function (fcall, fcall_len, &ret_len, &error);
|
||||
fret = searpc_server_call_function ("test", fcall, fcall_len, &ret_len, &error);
|
||||
g_assert (error == NULL);
|
||||
result = searpc_client_fret__string (fret, ret_len, &error);
|
||||
g_assert (error->message);
|
||||
@@ -208,7 +208,7 @@ void test_object_call (void *fixture, const void *data)
|
||||
|
||||
fcall = searpc_client_fcall__string ("get_maman_bar", "kitty",
|
||||
&fcall_len);
|
||||
fret = searpc_server_call_function (fcall, fcall_len, &ret_len, &error);
|
||||
fret = searpc_server_call_function ("test", fcall, fcall_len, &ret_len, &error);
|
||||
g_assert (error == NULL);
|
||||
result = searpc_client_fret__object (MAMAN_TYPE_BAR, fret, ret_len, &error);
|
||||
|
||||
@@ -254,7 +254,7 @@ void test_objlist_call (void *fixture, const void *data)
|
||||
|
||||
fcall = searpc_client_fcall__string_int ("get_maman_bar_list", "kitty", 10,
|
||||
&fcall_len);
|
||||
fret = searpc_server_call_function (fcall, fcall_len, &ret_len, &error);
|
||||
fret = searpc_server_call_function ("test", fcall, fcall_len, &ret_len, &error);
|
||||
g_assert (error == NULL);
|
||||
result = searpc_client_fret__objlist (MAMAN_TYPE_BAR, fret, ret_len, &error);
|
||||
g_free (fcall);
|
||||
@@ -266,7 +266,7 @@ void test_objlist_call (void *fixture, const void *data)
|
||||
|
||||
fcall = searpc_client_fcall__string_int ("get_maman_bar_list", "kitty", 0,
|
||||
&fcall_len);
|
||||
fret = searpc_server_call_function (fcall, fcall_len, &ret_len, &error);
|
||||
fret = searpc_server_call_function ("test", fcall, fcall_len, &ret_len, &error);
|
||||
g_assert (error == NULL);
|
||||
result = searpc_client_fret__objlist (MAMAN_TYPE_BAR, fret, ret_len, &error);
|
||||
g_free (fcall);
|
||||
@@ -284,11 +284,12 @@ main (int argc, char *argv[])
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
|
||||
searpc_server_init ();
|
||||
searpc_server_register_function (get_substring, "get_substring",
|
||||
searpc_create_service ("test");
|
||||
searpc_server_register_function ("test", get_substring, "get_substring",
|
||||
searpc_signature_string__string_int());
|
||||
searpc_server_register_function (get_maman_bar, "get_maman_bar",
|
||||
searpc_server_register_function ("test", get_maman_bar, "get_maman_bar",
|
||||
searpc_signature_object__string());
|
||||
searpc_server_register_function (get_maman_bar_list, "get_maman_bar_list",
|
||||
searpc_server_register_function ("test", get_maman_bar_list, "get_maman_bar_list",
|
||||
searpc_signature_objlist__string_int());
|
||||
|
||||
g_test_add ("/searpc/simple", void, NULL,
|
||||
|
Reference in New Issue
Block a user