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

update libpomelo #58

Merged
merged 2 commits into from
Jul 17, 2014
Merged
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
40 changes: 40 additions & 0 deletions include/pomelo.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ extern "C" {
#define PC_EVENT_TIMEOUT "timeout"
#define PC_EVENT_KICK "onKick"

#define PC_PROTO_VERSION "protoVersion"
#define PC_PROTO_CLIENT "clientProtos"
#define PC_PROTO_SERVER "serverProtos"

typedef struct pc_client_s pc_client_t;
typedef struct pc_listener_s pc_listener_t;
typedef struct pc_req_s pc_req_t;
Expand Down Expand Up @@ -94,6 +98,15 @@ typedef enum {
PC_TP_ST_CLOSED
} pc_transport_state;

/**
* operation for proto files.
*/
typedef enum {
PC_PROTO_OP_READ = 1,
PC_PROTO_OP_WRITE,
PC_PROTO_OP_UNKONWN
} pc_proto_op;

/**
* Callbacks
*/
Expand Down Expand Up @@ -186,6 +199,8 @@ typedef pc_buf_t (*pc_msg_encode_cb)(pc_client_t *client, uint32_t reqId,
*/
typedef void (*pc_msg_encode_done_cb)(pc_client_t *client, pc_buf_t buf);

typedef void (*pc_proto_cb)(pc_client_t *client, pc_proto_op op, const char* fileName, void *data);

/**
* Simple structure for memory block.
* The pc_buf_s is cheap and could be passed by value.
Expand Down Expand Up @@ -252,6 +267,10 @@ struct pc_client_s {
json_t *code_to_route;
json_t *server_protos;
json_t *client_protos;
json_t *proto_ver;
const char *proto_read_dir;
const char *proto_write_dir;
pc_proto_cb proto_event_cb;
pc_msg_parse_cb parse_msg;
pc_msg_parse_done_cb parse_msg_done;
pc_msg_encode_cb encode_msg;
Expand Down Expand Up @@ -479,6 +498,27 @@ void pc_emit_event(pc_client_t *client, const char *event, void *data);
*/
void pc_json_set_alloc_funcs(json_malloc_t malloc_fn, json_free_t free_fn);

/**
* Init protobuf settings, set the read/write proto files directorys
*
* @param client client instance.
* @param proto_read_dir directory of proto files to read.
* @param proto_write_dir directory of proto files to write.
*/
void pc_proto_init(pc_client_t *client, const char *proto_read_dir, const char *proto_write_dir);

/**
* Init protobuf settings, set the callback for read/write proto files
*
* @param client client instance.
* @param proto_cb callback when read or write proto files.
*/
void pc_proto_init2(pc_client_t *client, pc_proto_cb proto_cb);

void pc_proto_copy(pc_client_t *client, json_t *proto_ver, json_t *client_protos, json_t *server_protos);



/* Don't export the private CPP symbols. */
#undef PC_TCP_REQ_FIELDS
#undef PC_REQ_FIELDS
Expand Down
31 changes: 31 additions & 0 deletions src/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,10 @@ void pc__client_clear(pc_client_t *client) {
json_decref(client->client_protos);
client->client_protos = NULL;
}
if(client->proto_ver) {
json_decref(client->proto_ver);
client->proto_ver = NULL;
}
}

void pc_client_stop(pc_client_t *client) {
Expand Down Expand Up @@ -408,3 +412,30 @@ void pc__close_async_cb(uv_async_t *handle, int status) {
pc_client_t *client = (pc_client_t *)handle->data;
pc_client_stop(client);
}

void pc_proto_init(pc_client_t *client, const char *proto_read_dir, const char *proto_write_dir) {
if(!client) {
fprintf(stderr, "Fail to init protobuf, the client is null.\n");
return;
}
client->proto_read_dir = proto_read_dir;
client->proto_write_dir = proto_write_dir;
}

void pc_proto_init2(pc_client_t *client, pc_proto_cb proto_cb) {
if(!client) {
fprintf(stderr, "Fail to init protobuf, the client is null.\n");
return;
}
client->proto_event_cb = proto_cb;
}

void pc_proto_copy(pc_client_t *client, json_t *proto_ver, json_t *client_protos, json_t *server_protos) {
if (!client) {
fprintf(stderr, "Fail to copy protobuf info, one client is null.\n");
return;
}
client->proto_ver = proto_ver;
client->client_protos = client_protos;
client->server_protos = server_protos;
}
114 changes: 88 additions & 26 deletions src/pkg-handshake.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ static int pc__handshake_ack(pc_client_t *client);
static void pc__handshake_req_cb(uv_write_t* req, int status);
static void pc__handshake_ack_cb(uv_write_t* req, int status);

static void pc__load_file(pc_client_t *client, const char *name, json_t **dest);
static void pc__dump_file(pc_client_t *client, const char *name, json_t *src);

int pc__handshake_req(pc_client_t *client) {
json_t *handshake_opts = client->handshake_opts;
json_t *body = json_object();
Expand All @@ -36,13 +39,18 @@ int pc__handshake_req(pc_client_t *client) {
json_object_set(sys, "type", json_type);
json_object_set(sys, "version", json_version);

json_t *proto, *protoVersion;
proto = json_load_file("protoVersion", 0, &err);
if(proto) {
protoVersion = json_object_get(proto, "protoVersion");
json_object_set(sys, "protoVersion", protoVersion);
json_t *proto;
if(!client->proto_ver) {
pc__load_file(client, PC_PROTO_VERSION, &proto);
if(proto) {
client->proto_ver = json_object_get(proto, PC_PROTO_VERSION);
json_object_set(sys, PC_PROTO_VERSION, client->proto_ver);
}
} else {
json_object_set(sys, PC_PROTO_VERSION, client->proto_ver);
}


json_decref(json_type);
json_decref(json_version);
json_decref(proto);
Expand Down Expand Up @@ -126,29 +134,48 @@ int pc__handshake_resp(pc_client_t *client,
}

// setup protobuf data definition
json_t *protos = json_object_get(sys, "protos");

if(protos) {
client->server_protos = json_object_get(protos, "server");
client->client_protos = json_object_get(protos, "client");
json_incref(client->server_protos);
json_incref(client->client_protos);
json_t *t = json_object();
json_object_set(t, "protoVersion", json_object_get(protos, "version"));
json_dump_file(t, "protoVersion", 0);
json_decref(t);
json_dump_file(client->server_protos, "serverProtos", 0);
json_dump_file(client->client_protos, "clientProtos", 0);
json_t *useProto = json_object_get(sys, "useProto");
if(useProto) {
json_t *protos = json_object_get(sys, "protos");
if(protos) {
if(client->server_protos) {
json_decref(client->server_protos);
}
client->server_protos = json_object_get(protos, "server");
if(client->client_protos) {
json_decref(client->client_protos);
}
client->client_protos = json_object_get(protos, "client");
json_incref(client->server_protos);
json_incref(client->client_protos);

json_t *t = json_object();
json_object_set(t, PC_PROTO_VERSION, json_object_get(protos, "version"));
pc__dump_file(client, PC_PROTO_VERSION, t);
json_decref(t);

pc__dump_file(client, PC_PROTO_SERVER, client->server_protos);
pc__dump_file(client, PC_PROTO_CLIENT, client->client_protos);
} else {
if(!client->server_protos) {
pc__load_file(client, PC_PROTO_SERVER, &client->server_protos);
}
if(!client->client_protos) {
pc__load_file(client, PC_PROTO_CLIENT, &client->client_protos);
}
}
} else {
json_t *server_protos;
json_t *client_protos;
server_protos = json_load_file("serverProtos", 0, &error);
if(server_protos) {
client->server_protos = server_protos;
if(client->server_protos) {
json_decref(client->server_protos);
client->server_protos = NULL;
}
if(client->client_protos) {
json_decref(client->client_protos);
client->client_protos = NULL;
}
client_protos = json_load_file("clientProtos", 0, &error);
if(client_protos) {
client->client_protos = client_protos;
if(client->proto_ver) {
json_decref(client->proto_ver);
client->proto_ver = NULL;
}
}
}
Expand Down Expand Up @@ -250,3 +277,38 @@ static void pc__handshake_ack_cb(uv_write_t* req, int status) {
conn_req->cb(conn_req, status);
}
}

static void pc__load_file(pc_client_t *client, const char *name, json_t **dest) {
json_error_t err;
if(client->proto_event_cb) {
client->proto_event_cb(client, PC_PROTO_OP_READ, name, (void*)dest);
} else if(client->proto_read_dir) {
int offset = 0;
char path[100] = {0};
memcpy(path, client->proto_read_dir, 0);
offset += strlen(client->proto_read_dir);
memcpy(path, "/", offset);
offset += 1;
memcpy(path, name, offset);
*dest = json_load_file(path, 0, &err);
} else {
*dest = json_load_file(name, 0, &err);
}
}

static void pc__dump_file(pc_client_t *client, const char *name, json_t *src) {
if(client->proto_event_cb) {
client->proto_event_cb(client, PC_PROTO_OP_WRITE, name, (void*)src);
} else if(client->proto_write_dir) {
int offset = 0;
char path[100] = {0};
memcpy(path, client->proto_read_dir, 0);
offset += strlen(client->proto_read_dir);
memcpy(path, "/", offset);
offset += 1;
memcpy(path, name, offset);
json_dump_file(src, path, 0);
} else {
json_dump_file(src, name, 0);
}
}