1
0
mirror of https://github.com/haiwen/libsearpc.git synced 2025-09-02 05:14:48 +00:00

Multiple services support in searpc server.

This commit is contained in:
killing
2011-12-25 11:07:36 +08:00
parent 0b0d51accd
commit e0dbd4c248
5 changed files with 104 additions and 26 deletions

View File

@@ -77,7 +77,7 @@ static void
strlen_callback(void *vresult, void *user_data, GError *error) strlen_callback(void *vresult, void *user_data, GError *error)
{ {
const char *str = user_data; const char *str = user_data;
int len = (int)(long)vresult; int len = *((int *)vresult);
g_assert (strcmp(str, "user data") == 0); g_assert (strcmp(str, "user data") == 0);
printf("the length of string 'hello searpc' is %d.\n", len); printf("the length of string 'hello searpc' is %d.\n", len);

View File

@@ -29,13 +29,15 @@ static void
start_rpc_service(void) start_rpc_service(void)
{ {
searpc_server_init(); searpc_server_init();
searpc_create_service("searpc-demo");
/* The first parameter is the implementation function. /* The first parameter is the implementation function.
* The second parameter is the name of the rpc function the * The second parameter is the name of the rpc function the
* client would call. * client would call.
* The third parameter is the signature. * The third parameter is the signature.
*/ */
searpc_server_register_function(searpc_strlen, searpc_server_register_function("searpc-demo",
searpc_strlen,
"searpc_strlen", "searpc_strlen",
searpc_signature_int__string()); searpc_signature_int__string());
} }
@@ -106,7 +108,7 @@ main(int argc, char *argv[])
gsize ret_len; gsize ret_len;
int fcall_len = ntohs(pac->length); int fcall_len = ntohs(pac->length);
/* Execute the RPC function */ /* 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); &ret_len, &error);
pac_ret = (packet *)buf; pac_ret = (packet *)buf;

View File

@@ -27,6 +27,13 @@ typedef struct FuncItem {
MarshalItem *marshal; MarshalItem *marshal;
} FuncItem; } FuncItem;
typedef struct {
char *name;
GHashTable *func_table;
} SearpcService;
static GHashTable *marshal_table;
static GHashTable *service_table;
static void static void
func_item_free (FuncItem *item) func_item_free (FuncItem *item)
@@ -42,9 +49,42 @@ marshal_item_free (MarshalItem *item)
g_free (item); g_free (item);
} }
static GHashTable *marshal_table; int
static GHashTable *func_table; 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 */ /* Marshal functions */
static inline void static inline void
@@ -124,10 +164,10 @@ marshal_set_ret_common (JsonObject *object, gsize *len, GError *error)
void void
searpc_server_init () 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, marshal_table = g_hash_table_new_full (g_str_hash, g_str_equal,
NULL, (GDestroyNotify)marshal_item_free); 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 buildin marshal functions */
register_marshals(marshal_table); register_marshals(marshal_table);
@@ -136,7 +176,7 @@ searpc_server_init ()
void void
searpc_server_final() searpc_server_final()
{ {
g_hash_table_destroy (func_table); g_hash_table_destroy (service_table);
g_hash_table_destroy (marshal_table); g_hash_table_destroy (marshal_table);
} }
@@ -162,12 +202,18 @@ searpc_server_register_marshal (gchar *signature, SearpcMarshalFunc marshal)
} }
gboolean 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; FuncItem *item;
MarshalItem *mitem; 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); mitem = g_hash_table_lookup (marshal_table, signature);
if (!mitem) { if (!mitem) {
@@ -180,7 +226,7 @@ searpc_server_register_function (void *func, const gchar *fname, gchar *signatur
item->fname = g_strdup(fname); item->fname = g_strdup(fname);
item->func = func; 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); g_free (signature);
return TRUE; return TRUE;
@@ -188,8 +234,10 @@ searpc_server_register_function (void *func, const gchar *fname, gchar *signatur
/* Called by RPC transport. */ /* Called by RPC transport. */
gchar* 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; JsonParser *parser;
JsonNode *root; JsonNode *root;
JsonArray *array; JsonArray *array;
@@ -200,6 +248,13 @@ searpc_server_call_function (gchar *func, gsize len, gsize *ret_len, GError **er
#endif #endif
g_return_val_if_fail (error == NULL || *error == NULL, NULL); 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 (); 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); array = json_node_get_array (root);
const char *fname = json_array_get_string_element(array, 0); 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) { if (!fitem) {
g_warning ("[SeaRPC] cannot find function %s.\n", fname); g_warning ("[SeaRPC] cannot find function %s.\n", fname);
g_set_error (error, 0, 500, "cannot find function %s.", fname); g_set_error (error, 0, 500, "cannot find function %s.", fname);

View File

@@ -22,6 +22,23 @@ void searpc_server_init ();
*/ */
void searpc_server_final (); 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: * searpc_server_register_marshal:
* *
@@ -36,26 +53,29 @@ gboolean searpc_server_register_marshal (gchar *signature,
/** /**
* searpc_server_register_function: * 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 * @signature: the signature of the function, register_function() will take
* owner of this string. * owner of this string.
*/ */
gboolean searpc_server_register_function (void* func, gboolean searpc_server_register_function (const char *service,
void* func,
const gchar *fname, const gchar *fname,
gchar *signature); gchar *signature);
/** /**
* searpc_server_call_function: * searpc_server_call_function:
* @service: service name.
* @func: the serialized representation of the function to call. * @func: the serialized representation of the function to call.
* @len: length of @func. * @len: length of @func.
* @ret_len: the length of the returned string. * @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. * 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); GError **error);
/** /**

View File

@@ -172,7 +172,7 @@ void test_simple_call (void *fixture, const void *data)
fcall = searpc_client_fcall__string_int ("get_substring", "hello", 2, fcall = searpc_client_fcall__string_int ("get_substring", "hello", 2,
&fcall_len); &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); g_assert (error == NULL);
result = searpc_client_fret__string (fret, ret_len, &error); result = searpc_client_fret__string (fret, ret_len, &error);
g_assert (strcmp(result, "he") == 0); g_assert (strcmp(result, "he") == 0);
@@ -184,7 +184,7 @@ void test_simple_call (void *fixture, const void *data)
result = NULL; result = NULL;
fcall = searpc_client_fcall__string_int ("get_substring", "hello", 7, fcall = searpc_client_fcall__string_int ("get_substring", "hello", 7,
&fcall_len); &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); g_assert (error == NULL);
result = searpc_client_fret__string (fret, ret_len, &error); result = searpc_client_fret__string (fret, ret_len, &error);
g_assert (error->message); 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 = searpc_client_fcall__string ("get_maman_bar", "kitty",
&fcall_len); &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); g_assert (error == NULL);
result = searpc_client_fret__object (MAMAN_TYPE_BAR, fret, ret_len, &error); 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 = searpc_client_fcall__string_int ("get_maman_bar_list", "kitty", 10,
&fcall_len); &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); g_assert (error == NULL);
result = searpc_client_fret__objlist (MAMAN_TYPE_BAR, fret, ret_len, &error); result = searpc_client_fret__objlist (MAMAN_TYPE_BAR, fret, ret_len, &error);
g_free (fcall); 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 = searpc_client_fcall__string_int ("get_maman_bar_list", "kitty", 0,
&fcall_len); &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); g_assert (error == NULL);
result = searpc_client_fret__objlist (MAMAN_TYPE_BAR, fret, ret_len, &error); result = searpc_client_fret__objlist (MAMAN_TYPE_BAR, fret, ret_len, &error);
g_free (fcall); g_free (fcall);
@@ -284,11 +284,12 @@ main (int argc, char *argv[])
g_test_init (&argc, &argv, NULL); g_test_init (&argc, &argv, NULL);
searpc_server_init (); 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_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_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()); searpc_signature_objlist__string_int());
g_test_add ("/searpc/simple", void, NULL, g_test_add ("/searpc/simple", void, NULL,