Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

small fixes #69

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 30 additions & 30 deletions README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ server side should take an extra GError argument to report error. The
returned json object contains three fields:

* **ret**: the return value of the RPC function
* **err_code**: error code. This field is only set if the RPC function
* **err_code**: error code. This field is only set if the RPC function
reports an error.
* **err_msg**: error message. This field is only set if the RPC function
* **err_msg**: error message. This field is only set if the RPC function
reports an error.

Compile
Expand All @@ -23,11 +23,11 @@ Compile
Just

./autogen.sh; ./configure; make; make install

To enable profile, Use

CFLAGS="-DPROFILE" ./configure

When profile is enabled, the time spend in each rpc call will be printed.

Example
Expand Down Expand Up @@ -57,7 +57,7 @@ transport function. For example:
Suppose we have a `get_substring` function defined in server as follows:

gchar *get_substring (const gchar *orig_str, int sub_len, GError **error)

To call this function, we type:

gchar* result;
Expand All @@ -70,15 +70,15 @@ is the function name. The remain parameters specify the number of parameters the
function took and the type of each parameter and its value. So

2, "string", "hello", "int", 2

means "get_substring" takes 2 parameters, the first is of type "string", the value is
"hello", the second is of type "int", the value is 2.


### Transport function ###

When the client-side function is called, Searpc does the following work:

* Pack the function name and the params into JSON data format.
* Call your transport function to send the JSON data
to the server, and get the returned data from the server.
Expand All @@ -90,9 +90,9 @@ Your transport function is supposed to:
* Send the request data to the server.
* Receive the returned data from the server.

The prototype of the transport function is:
The prototype of the transport function is:

/*
/*
* arg: rpc_client->arg. Normally a socket number.
* fcall_str: the JSON data stream generated by Searpc.
* fcall_len: the length of `fcall_str`.
Expand All @@ -101,7 +101,7 @@ The prototype of the transport function is:
*/
static char *transport_callback (void *arg, const char *fcall_str, size_t fcall_len, size_t *ret_len);


Server
------

Expand All @@ -119,7 +119,7 @@ And Searpc handles the others for you.
JSON data, call the RPC function and packing the result into JSON
data format is called marshalling. The function used to
pack the result is called a **marshal**.

* **Signature**: Every function has a signature determined by its
return type and parameter types. Knowning a function's signature
enable us to use a corresponding marshal to call it and convert
Expand All @@ -130,7 +130,7 @@ And Searpc handles the others for you.

First write rpc_table.py to contain the rpc function signatures as follows:


# [ <ret-type>, [<arg_types>] ]
func_table = [
[ "int", ["string"] ],
Expand All @@ -139,9 +139,9 @@ First write rpc_table.py to contain the rpc function signatures as follows:

Add makefile rule:

searpc-signature.h searpc-marshal.h: rpc_table.py
python searpc-codegen.py rpc_table.py
searpc-signature.h searpc-marshal.h &: rpc_table.py
searpc-codegen.py $<

`searpc-signature.h` and `searpc-marshal.h` will be created containing the
function signatures and corresponding marshals. `searpc-marshal.h` also contains
a function called `register_marshals`.
Expand All @@ -158,12 +158,12 @@ Then we init the server as follows:
/* register_marshals is defined in searpc-marshal.h */
searpc_server_init(register_marshals);
}


### Register Functions ###

To register a function we first need to create a service. A service is
a set of functions.
a set of functions.

Suppose we want to make `searpc_strlen` callable from some network
clients, we can do this by putting the following code somewhere:
Expand All @@ -176,15 +176,15 @@ clients, we can do this by putting the following code somewhere:
else
return strlen(str);
}

static void
register_functions()
{

searpc_create_service("searpc-demo");

/* 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.
* The third parameter is the signature.
*/
Expand All @@ -194,15 +194,15 @@ clients, we can do this by putting the following code somewhere:
searpc_signature_int__string());
}


The `seaprc_server_register_function` routine registers a function as
a RPC function. The
prototype of this function is:

/*
* service: the name of the service
* func: pointer to the function you want to register
* fname: the name of the function. It would be the key of your
* fname: the name of the function. It would be the key of your
* function in the fucntion hash table.
* signature: the identifier used to get the corresponding marshal.
* Returns: a gboolean value indicating success or failure
Expand All @@ -225,9 +225,9 @@ following work for you:
* Lookup the function in internal function table according to the funcname.
* If a proper function is found, call the function with the given params.
* Packing the result into a JSON data string.

The prototype of `searpc_server_call_function` is:

/*
* service: Service name.
* data: The incoming JSON data stream.
Expand All @@ -239,15 +239,15 @@ The prototype of `searpc_server_call_function` is:
gchar *data, gsize len, gsize *ret_len)

The value returned by `searpc_server_call_function()` is the JSON data
ready to send back to the client.
ready to send back to the client.

Note, the JSON data stream from client does not contain the service
name, it's left to the transport layer to solve the problem. There are
several ways, for example:

1. You may listen on different sockets and determine the service by
the incoming socket.
2. The client transport function prepend the service name into the request
2. The client transport function prepend the service name into the request
before the json data, and the server transport function first read the service
name and read the json data.

Expand All @@ -267,7 +267,7 @@ function which accepts multiple params, here is an example:
def call_remote_func_sync(self, fcall_str):
# your transport code here
...

@searpc_func("int", ["string", "string"])
def searpc_demo_func(self):
# this is enough for the client side
Expand All @@ -279,7 +279,7 @@ See the demo program for a more detailed example.
Demos
=====

There are well-commented demos in both C and Python.
There are well-commented demos in both C and Python.

* **searpc-demo-server.c**: The server side demo program
* **searpc-demo-client.c**: The client side demo in C
Expand All @@ -295,7 +295,7 @@ Dependency

The following packages are required to build libsearpc:

* glib-2.0 >= 2.26.0
* glib-2.0 >= 2.26.0
* gobject-2.0 >= 2.26.0
* jansson >= 2.2.1
* python simplejson (for pysearpc)
8 changes: 4 additions & 4 deletions demo/demo-async-client.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ static int transport_send(void *arg, char *fcall_str,
int fd, ret;
char buf[BUFLEN];
packet *pac, *pac_ret;

pac = (packet *)buf;

/* construct the packet */
Expand All @@ -52,7 +52,7 @@ static int transport_send(void *arg, char *fcall_str,

trans->rpc_priv = rpc_priv;
g_free (fcall_str);

return 0;
}

Expand All @@ -69,7 +69,7 @@ transport_read(TcpTransport *trans)
fprintf(stderr, "read packet failed: %s\n", strerror(errno));
exit(-1);
}

ret_len = ntohs(pac->length);
searpc_client_generic_callback (pac->data, ret_len, trans->rpc_priv, NULL);
trans->rpc_priv = NULL;
Expand All @@ -80,7 +80,7 @@ strlen_callback(void *vresult, void *user_data, GError *error)
{
const char *str = user_data;
int len = *((int *)vresult);

g_assert (strcmp(str, "user data") == 0);
printf("the length of string 'hello searpc' is %d.\n", len);
}
Expand Down
4 changes: 2 additions & 2 deletions demo/pysearpc-demo-client.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def recv_all(sock, length):
return data

class SampleRpcClient(SearpcClient):

def call_remote_func_sync(self, fcall_str):
"""
called by searpc_func to send the request and receive the result
Expand All @@ -34,7 +34,7 @@ def call_remote_func_sync(self, fcall_str):
# connect to server
s.connect((SERVER_ADDR, SERVER_PORT))
# send the header
header = pack('!h', len(fcall_str));
header = pack('!h', len(fcall_str));
s.sendall(header)
# send the JSON data
s.sendall(fcall_str)
Expand Down
12 changes: 6 additions & 6 deletions demo/searpc-demo-client.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ static char *transport_callback(void *arg, const char *fcall_str,
int fd, ret;
char buf[BUFLEN];
packet *pac, *pac_ret;

fd = (int)(long) arg;
pac = (packet *)buf;

Expand All @@ -47,14 +47,14 @@ static char *transport_callback(void *arg, const char *fcall_str,
fprintf (stderr, "write failed: %s\n", strerror(errno));
exit(-1);
}

/* read the returned packet */
pac_ret = read_packet(fd, buf);
if (pac_ret == NULL) {
fprintf(stderr, "read packet failed: %s\n", strerror(errno));
exit(-1);
}

*ret_len = ntohs(pac_ret->length);

return g_strndup(pac_ret->data, *ret_len);
Expand All @@ -65,7 +65,7 @@ void
searpc_set_objlist_to_ret_object (json_t *object, GList *ret)
{
GList *ptr;

if (ret == NULL)
json_object_set_new (object, "ret", json_null ());
else {
Expand Down Expand Up @@ -141,9 +141,9 @@ rpc_glist_test(int sockfd, struct sockaddr_in *servaddr, SearpcClient *rpc_clien
if (error != NULL) {
fprintf(stderr, "error: %s\n", error->message);
exit(-1);
}
}
else printf("%s\n", json_dumps (object, JSON_INDENT(2)));

json_t *array = json_object_get (object, "ret");
if (json_array_size(array) != count) {
printf("Glisttest fail.\n");
Expand Down
8 changes: 4 additions & 4 deletions demo/searpc-demo-packet.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#include <winsock2.h>
#include <ctype.h>
#include <ws2tcpip.h>
#define UNUSED
#define UNUSED
#else
#include <arpa/inet.h>
#endif
Expand Down Expand Up @@ -64,7 +64,7 @@ readn(int fd, char *buf, size_t n)
if ( (nread = recv(fd, buf, nleft, 0)) < 0) {
#else
if ( (nread = read(fd, buf, nleft)) < 0) {
#endif
#endif
if (errno == EINTR)
nread = 0; /* and call read() again */
else
Expand All @@ -76,7 +76,7 @@ readn(int fd, char *buf, size_t n)
buf += nread;
}

return(n - nleft); /* return >= 0 */
return(n - nleft); /* return >= 0 */
}


Expand All @@ -101,7 +101,7 @@ read_packet(int sockfd, char *buf)

return pac;
}

#endif


Expand Down
7 changes: 3 additions & 4 deletions demo/searpc-demo-server.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ start_rpc_service(void)
searpc_create_service("searpc-demo");

/* 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.
* The third parameter is the signature.
*/
Expand Down Expand Up @@ -129,8 +129,6 @@ main(int argc, char *argv[])
}

while (1) {
GError *error = NULL;

clilen = sizeof(client_addr);
connfd = accept(listenfd, (struct sockaddr *)&client_addr, &clilen);
if (connfd < 0) {
Expand All @@ -143,7 +141,7 @@ main(int argc, char *argv[])
if (pac == NULL) {
fprintf(stderr, "read packet failed: %s\n", strerror(errno));
exit(-1);
}
}

gsize ret_len;
int fcall_len = ntohs(pac->length);
Expand All @@ -153,6 +151,7 @@ main(int argc, char *argv[])
pac_ret = (packet *)buf;
pac_ret->length = htons((uint16_t)ret_len);
memcpy(pac_ret->data, res, ret_len);
free(res);

/* send the ret packet */
if (writen (connfd, buf, PACKET_HEADER_LENGTH + ret_len) == -1) {
Expand Down
Loading