示例#1
0
static int
_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 , type | PTYPE_TAG_DONTCOPY, session, (void *)msg, sz);
		return 1;
	}

	int fd = h->remote_fd[harbor_id];
	if (fd >= 0) {
		struct remote_message_header cookie;
		cookie.source = source;
		cookie.destination = (destination & HANDLE_MASK) | ((uint32_t)type << HANDLE_REMOTE_SHIFT);
		cookie.session = (uint32_t)session;
		int err = _send_remote(fd, msg,sz,&cookie);
		if (err) {
			close(fd);
			h->remote_fd[harbor_id] = _connect_to(context, h->remote_addr[harbor_id]);
			if (h->remote_fd[harbor_id] < 0) {
				skynet_error(context, "Reconnect to harbor %d : %s failed", harbor_id, h->remote_addr[harbor_id]);
				return 0;
			}
		}
	} else {
		_request_master(h, context, NULL, 0, harbor_id);
		skynet_error(context, "Drop message to harbor %d from %x to %x (session = %d, msgsz = %d)",harbor_id, source, destination,session,(int)sz);
	}
	return 0;
}
示例#2
0
static void
_dispatch_queue(struct harbor *h, struct skynet_context * context, struct msg_queue * queue, uint32_t handle,  const char name[GLOBALNAME_LENGTH] ) {
	int harbor_id = handle >> HANDLE_REMOTE_SHIFT;
	assert(harbor_id != 0);
	int fd = h->remote_fd[harbor_id];
	if (fd < 0) {
		char tmp [GLOBALNAME_LENGTH+1];
		memcpy(tmp, name , GLOBALNAME_LENGTH);
		tmp[GLOBALNAME_LENGTH] = '\0';
		skynet_error(context, "Drop message to %s (in harbor %d)",tmp,harbor_id);
		return;
	}
	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 & HANDLE_MASK);
		_header_to_message(cookie, (uint32_t *)cookie);
		int err = _send_package(fd, m->buffer, m->size);
		if (err) {
			close(fd);
			h->remote_fd[harbor_id] = _connect_to(context, h->remote_addr[harbor_id]);
			if (h->remote_fd[harbor_id] < 0) {
				skynet_error(context, "Reconnect to harbor %d %s failed",harbor_id, h->remote_addr[harbor_id]);
				return;
			}
		}
		free(m->buffer);
		m = _pop_queue(queue);
	}
}
HARBOR_API int
harbor_init(struct harbor *h, struct skynet_context *ctx, const char * args) {
	h->ctx = ctx;
	int sz = strlen(args)+1;
	//char master_addr[sz];
	//char local_addr[sz];
	char master_addr[100];
	char local_addr[100];
	int harbor_id = 0;
	sscanf(args,"%s %s %d",master_addr, local_addr, &harbor_id);
	h->master_addr = skynet_strdup(master_addr);
	h->id = harbor_id;
	h->master_fd = _connect_to(h, master_addr, true);
	if (h->master_fd == -1) {
		fprintf(stderr, "Harbor: Connect to master failed\n");
		exit(1);
	}
	h->local_addr = skynet_strdup(local_addr);

	_launch_gate(ctx, local_addr);
	skynet_callback(ctx, h, _mainloop);
	_request_master(h, local_addr, strlen(local_addr), harbor_id);

	return 0;
}
示例#4
0
static void
_update_address(struct skynet_context * context, struct master *m, int harbor_id, const char * buffer, size_t sz) {
	if (m->remote_fd[harbor_id] >= 0) {
		close(m->remote_fd[harbor_id]);
		m->remote_fd[harbor_id] = -1;
	}
	free(m->remote_addr[harbor_id]);
	char * addr = malloc(sz+1);
	memcpy(addr, buffer, sz);
	addr[sz] = '\0';
	m->remote_addr[harbor_id] = addr;
	int fd = _connect_to(addr);
	if (fd<0) {
		skynet_error(context, "Can't connect to harbor %d : %s", harbor_id, addr);
		return;
	}
	m->remote_fd[harbor_id] = fd;
	_broadcast(context, m, addr, sz, harbor_id);

	int i;
	for (i=1;i<REMOTE_MAX;i++) {
		if (i == harbor_id)
			continue;
		const char * addr = m->remote_addr[i];
		if (addr == NULL) {
			continue;
		}
		_send_to(fd, addr, strlen(addr), i);
	}
}
static void
_update_address(struct master *m, int harbor_id, const char * buffer, size_t sz) {
	if (m->remote_fd[harbor_id] >= 0) {
		close_harbor(m, harbor_id);
	}
	skynet_free(m->remote_addr[harbor_id]);
	char * addr = (char*)skynet_malloc(sz+1);
	memcpy(addr, buffer, sz);
	addr[sz] = '\0';
	m->remote_addr[harbor_id] = addr;
	_connect_to(m, harbor_id);
}
static void
_update_remote_address(struct harbor *h, int harbor_id, const char * ipaddr) {
	if (harbor_id == h->id) {
		return;
	}
	assert(harbor_id > 0  && harbor_id< REMOTE_MAX);
	struct skynet_context * context = h->ctx;
	if (h->remote_fd[harbor_id] >=0) {
		skynet_socket_close(context, h->remote_fd[harbor_id]);
		skynet_free(h->remote_addr[harbor_id]);
		h->remote_addr[harbor_id] = NULL;
	}
	h->remote_fd[harbor_id] = _connect_to(h, ipaddr, false);
	h->connected[harbor_id] = false;
}
示例#7
0
static void
_update_remote_address(struct skynet_context * context, struct harbor *h, int harbor_id, const char * ipaddr) {
	if (harbor_id == h->id) {
		return;
	}
	assert(harbor_id > 0  && harbor_id< REMOTE_MAX);
	if (h->remote_fd[harbor_id] >=0) {
		close(h->remote_fd[harbor_id]);
		free(h->remote_addr[harbor_id]);
		h->remote_addr[harbor_id] = NULL;
	}
	h->remote_fd[harbor_id] = _connect_to(context, ipaddr);
	if (h->remote_fd[harbor_id] >= 0) {
		free(h->remote_addr[harbor_id]);
		h->remote_addr[harbor_id] = strdup(ipaddr);
	}
}
示例#8
0
static void
_request_master(struct harbor *h, struct skynet_context * context, const char name[GLOBALNAME_LENGTH], size_t i, uint32_t handle) {
	char buffer[4+i];
	handle = htonl(handle);
	memcpy(buffer, &handle, 4);
	memcpy(buffer+4,name,i);

	int err = _send_package(h->master_fd, buffer, 4+i);
	if (err) {
		close(h->master_fd);
		h->master_fd = _connect_to(context, h->master_addr);
		if (h->master_fd < 0) {
			skynet_error(context, "Reconnect to master server %s failed", h->master_addr);
			return;
		}
		_send_package(h->master_fd, buffer, 4+i); 
	}
}
示例#9
0
int
harbor_init(struct harbor *h, struct skynet_context *ctx, const char * args) {
	int sz = strlen(args)+1;
	char master_addr[sz];
	char local_addr[sz];
	int harbor_id = 0;
	sscanf(args,"%s %s %d",master_addr, local_addr, &harbor_id);
	int master_fd = _connect_to(ctx, master_addr);
	if (master_fd < 0) {
		skynet_error(ctx, "Harbor : Connect to master %s faild",master_addr);
		return 1;
	}
	printf("Connect to master %s\n",master_addr);

	h->master_addr = strdup(master_addr);
	h->master_fd = master_fd;

	char tmp[128];
	sprintf(tmp,"gate L ! %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");
		return 1;
	}
	uint32_t gate = strtoul(gate_addr+1 , NULL, 16);
	if (gate == 0) {
		skynet_error(ctx, "Harbor : launch gate invalid %s", gate_addr);
		return 1;
	}
	const char * self_addr = skynet_command(ctx, "REG", NULL);
	int n = sprintf(tmp,"broker %s",self_addr);
	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);

	_report_local_address(h, ctx, local_addr, harbor_id);

	return 0;
}
示例#10
0
static void
_broadcast(struct skynet_context * context, struct master *m, const char *name, size_t sz, uint32_t handle) {
	int i;
	for (i=1;i<REMOTE_MAX;i++) {
		int fd = m->remote_fd[i];
		if (fd < 0)
			continue;
		int err = _send_to(fd, name, sz, handle);
		if (err) {
			close(fd);
			fd = _connect_to(m->remote_addr[i]);
			if (fd < 0) {
				m->remote_fd[i] = -1;
				skynet_error(context, "Reconnect to harbor %d : %s faild", i, m->remote_addr[i]);
			}
			else {
				if (_send_to(fd, name, sz, handle)) {
					close(fd);
					m->remote_fd[i] = -1;
				}
			}
		}
	}
}