support multi protocol

This commit is contained in:
云风
2012-08-31 21:18:19 +08:00
parent 1ee802c5c5
commit 0a886cd57c
47 changed files with 542 additions and 520 deletions

View File

@@ -9,7 +9,7 @@
#include <string.h>
static int
_cb(struct skynet_context * context, void * ud, int session, uint32_t source, const void * msg, size_t sz) {
_cb(struct skynet_context * context, void * ud, int type, int session, uint32_t source, const void * msg, size_t sz) {
assert(sz <= 65535);
int fd = (int)(intptr_t)ud;

View File

@@ -40,6 +40,10 @@ struct hashmap {
struct keyvalue *node[HASH_SIZE];
};
/*
message type (8bits) is in destination high 8bits
harbor id (8bits) is also in that place , but remote message doesn't need harbor id.
*/
struct remote_message_header {
uint32_t source;
uint32_t destination;
@@ -354,7 +358,7 @@ _dispatch_queue(struct harbor *h, struct skynet_context * context, struct msg_qu
struct msg * m = _pop_queue(queue);
while (m) {
struct remote_message_header * cookie = (struct remote_message_header *)(m->buffer + m->size - sizeof(*cookie));
cookie->destination = handle;
cookie->destination |= (handle & 0xffffff);
_header_to_message(cookie, (uint32_t *)cookie);
int err = _send_package(fd, m->buffer, m->size);
if (err) {
@@ -411,12 +415,12 @@ _request_master(struct harbor *h, struct skynet_context * context, const char na
*/
static int
_remote_send_handle(struct harbor *h, struct skynet_context * context, uint32_t source, uint32_t destination, int session, const char * msg, size_t sz) {
_remote_send_handle(struct harbor *h, struct skynet_context * context, uint32_t source, uint32_t destination, int type, int session, const char * msg, size_t sz) {
int harbor_id = destination >> HANDLE_REMOTE_SHIFT;
assert(harbor_id != 0);
if (harbor_id == h->id) {
// local message
skynet_send(context, source, destination , session, (void *)msg, sz, DONTCOPY);
skynet_send(context, source, destination , type | PTYPE_TAG_DONTCOPY, session, (void *)msg, sz);
return 1;
}
@@ -424,7 +428,7 @@ _remote_send_handle(struct harbor *h, struct skynet_context * context, uint32_t
if (fd >= 0) {
struct remote_message_header cookie;
cookie.source = source;
cookie.destination = destination;
cookie.destination = (destination & 0xffffff) | ((uint32_t)type << 24);
cookie.session = (uint32_t)session;
int err = _send_remote(fd, msg,sz,&cookie);
if (err) {
@@ -456,7 +460,7 @@ _remote_register_name(struct harbor *h, struct skynet_context * context, const c
}
static int
_remote_send_name(struct harbor *h, struct skynet_context * context, uint32_t source, const char name[GLOBALNAME_LENGTH], int session, const char * msg, size_t sz) {
_remote_send_name(struct harbor *h, struct skynet_context * context, uint32_t source, const char name[GLOBALNAME_LENGTH], int type, int session, const char * msg, size_t sz) {
struct keyvalue * node = _hash_search(h->map, name);
if (node == NULL) {
node = _hash_insert(h->map, name);
@@ -467,14 +471,14 @@ _remote_send_name(struct harbor *h, struct skynet_context * context, uint32_t so
}
struct remote_message_header header;
header.source = source;
header.destination = 0;
header.destination = type << 24;
header.session = (uint32_t)session;
_push_queue(node->queue, msg, sz, &header);
// 0 for request
_remote_register_name(h, context, name, 0);
return 1;
} else {
return _remote_send_handle(h, context, source, node->value, session, msg, sz);
return _remote_send_handle(h, context, source, node->value, type, session, msg, sz);
}
}
@@ -485,9 +489,11 @@ _report_local_address(struct harbor *h, struct skynet_context * context, const c
}
static int
_mainloop(struct skynet_context * context, void * ud, int session, uint32_t source, const void * msg, size_t sz) {
_mainloop(struct skynet_context * context, void * ud, int type, int session, uint32_t source, const void * msg, size_t sz) {
struct harbor * h = ud;
if (session == SESSION_CLIENT) {
switch (type) {
case PTYPE_HARBOR: {
// remote message in
const char * cookie = msg;
cookie += sz - 12;
struct remote_message_header header;
@@ -511,28 +517,37 @@ _mainloop(struct skynet_context * context, void * ud, int session, uint32_t sour
_update_remote_name(h, context, msg, header.destination);
}
} else {
skynet_send(context, header.source, header.destination, (int)header.session, (void *)msg, sz-12, DONTCOPY);
uint32_t destination = header.destination;
int type = (destination >> 24) | PTYPE_TAG_DONTCOPY;
destination = (destination & 0xffffff) | ((uint32_t)h->id << 24);
skynet_send(context, header.source, destination, type, (int)header.session, (void *)msg, sz-12);
return 1;
}
} else {
return 0;
}
case PTYPE_SYSTEM: {
// register name message
const struct remote_message *rmsg = msg;
assert (sz == sizeof(rmsg->destination));
_remote_register_name(h, context, rmsg->destination.name, rmsg->destination.handle);
return 0;
}
default: {
// remote message out
const struct remote_message *rmsg = msg;
if (sz == sizeof(rmsg->destination)) {
_remote_register_name(h, context, rmsg->destination.name, rmsg->destination.handle);
return 0;
}
assert(sz == sizeof(*rmsg));
if (rmsg->destination.handle == 0) {
if (_remote_send_name(h, context, source , rmsg->destination.name, session, rmsg->message, rmsg->sz)) {
if (_remote_send_name(h, context, source , rmsg->destination.name, type, session, rmsg->message, rmsg->sz)) {
return 0;
}
} else {
if (_remote_send_handle(h, context, source , rmsg->destination.handle, session, rmsg->message, rmsg->sz)) {
if (_remote_send_handle(h, context, source , rmsg->destination.handle, type, session, rmsg->message, rmsg->sz)) {
return 0;
}
}
free((void *)rmsg->message);
return 0;
}
}
return 0;
}
int
@@ -553,7 +568,7 @@ harbor_init(struct harbor *h, struct skynet_context *ctx, const char * args) {
h->master_fd = master_fd;
char tmp[128];
sprintf(tmp,"gate ! %s %d 0",local_addr,REMOTE_MAX);
sprintf(tmp,"gate ! %s %d %d 0",local_addr, PTYPE_HARBOR, REMOTE_MAX);
const char * gate_addr = skynet_command(ctx, "LAUNCH", tmp);
if (gate_addr == NULL) {
skynet_error(ctx, "Harbor : launch gate failed");
@@ -566,8 +581,8 @@ harbor_init(struct harbor *h, struct skynet_context *ctx, const char * args) {
}
const char * self_addr = skynet_command(ctx, "REG", NULL);
int n = sprintf(tmp,"broker %s",self_addr);
skynet_send(ctx, 0, gate, 0, tmp, n, 0);
skynet_send(ctx, 0, gate, 0, "start", 5, 0);
skynet_send(ctx, 0, gate, PTYPE_TEXT, 0, tmp, n);
skynet_send(ctx, 0, gate, PTYPE_TEXT, 0, "start", 5);
h->id = harbor_id;
skynet_callback(ctx, h, _mainloop);

View File

@@ -242,9 +242,12 @@ _update_address(struct skynet_context * context, struct master *m, int harbor_id
*/
static int
_mainloop(struct skynet_context * context, void * ud, int session, uint32_t source, const void * msg, size_t sz) {
_mainloop(struct skynet_context * context, void * ud, int type, int session, uint32_t source, const void * msg, size_t sz) {
if (type != PTYPE_HARBOR) {
skynet_error(context, "None harbor message recv from %x (type = %d)", source, type);
return 0;
}
struct master *m = ud;
assert(session == SESSION_CLIENT);
uint32_t handle = 0;
memcpy(&handle, msg, 4);
handle = ntohl(handle);
@@ -266,7 +269,7 @@ _mainloop(struct skynet_context * context, void * ud, int session, uint32_t sour
int
master_init(struct master *m, struct skynet_context *ctx, const char * args) {
char tmp[strlen(args) + 32];
sprintf(tmp,"gate ! %s %d 0",args,REMOTE_MAX);
sprintf(tmp,"gate ! %s %d %d 0",args,PTYPE_HARBOR,REMOTE_MAX);
const char * gate_addr = skynet_command(ctx, "LAUNCH", tmp);
if (gate_addr == NULL) {
skynet_error(ctx, "Master : launch gate failed");
@@ -279,8 +282,8 @@ master_init(struct master *m, struct skynet_context *ctx, const char * args) {
}
const char * self_addr = skynet_command(ctx, "REG", NULL);
int n = sprintf(tmp,"broker %s",self_addr);
skynet_send(ctx, 0, gate, 0, tmp, n, 0);
skynet_send(ctx, 0, gate, 0, "start", 5, 0);
skynet_send(ctx, 0, gate, PTYPE_TEXT, 0, tmp, n);
skynet_send(ctx, 0, gate, PTYPE_TEXT, 0, "start", 5);
skynet_callback(ctx, m, _mainloop);

View File

@@ -16,9 +16,9 @@ multicast_release(struct skynet_multicast_group *g) {
}
static int
_maincb(struct skynet_context * context, void * ud, int session, uint32_t source, const void * msg, size_t sz) {
_maincb(struct skynet_context * context, void * ud, int type, int session, uint32_t source, const void * msg, size_t sz) {
struct skynet_multicast_group *g = ud;
if (source == 0) {
if (type == PTYPE_SYSTEM) {
char cmd = '\0';
uint32_t handle = 0;
sscanf(msg,"%c %x",&cmd,&handle);
@@ -42,6 +42,7 @@ _maincb(struct skynet_context * context, void * ud, int session, uint32_t source
}
return 0;
} else {
sz |= type << 24;
struct skynet_multicast_message * mc = skynet_multicast_create(msg, sz, source);
skynet_multicast_castgroup(context, g, mc);
return 1;

View File

@@ -2,7 +2,7 @@
#include <stdio.h>
static int
_cb(struct skynet_context * context, void * ud, int session, uint32_t source, const void * msg, size_t sz) {
_cb(struct skynet_context * context, void * ud, int type, int session, uint32_t source, const void * msg, size_t sz) {
uint32_t dest = (uint32_t)(uintptr_t)ud;
skynet_forward(context, dest);
return 0;