示例#1
0
int 
skynet_multicast_castgroup(struct skynet_context * from, struct skynet_multicast_group * group, struct skynet_multicast_message *msg) {
	combine_queue(from, group);
	int release = 0;
	if (group->number > 0) {
		uint32_t source = skynet_context_handle(from);
		skynet_multicast_copy(msg, group->number);
		int i;
		for (i=0;i<group->number;i++) {
			uint32_t p = group->data[i];
			struct skynet_context * ctx = skynet_handle_grab(p);
			if (ctx) {
				skynet_context_send(ctx, msg, 0 , source, PTYPE_MULTICAST , 0);
				skynet_context_release(ctx);
			} else {
				skynet_multicast_leavegroup(group, p);
				++release;
			}
		}
	}
	
	skynet_multicast_copy(msg, -release);
	
	return group->number - release;
}
示例#2
0
int 
skynet_multicast_castgroup(struct skynet_context * from, struct skynet_multicast_group * group, struct skynet_multicast_message *msg) {
	combine_queue(from, group);
	if (group->number == 0) {
		skynet_multicast_dispatch(msg, NULL, NULL);
		return 0;
	}
	uint32_t source = skynet_context_handle(from);
	skynet_multicast_copy(msg, group->number);
	int i;
	int release = 0;
	for (i=0;i<group->number;i++) {
		struct pair * p = &group->data[i];
		skynet_context_send(p->ctx, msg, 0 , source, PTYPE_MULTICAST , 0);
		int ref = skynet_context_ref(p->ctx);
		if (ref == 1) {
			skynet_context_release(p->ctx);
			struct skynet_context * ctx = skynet_handle_grab(p->handle);
			if (ctx == NULL) {
				p->ctx = NULL;
				skynet_multicast_leavegroup(group, p->handle);
				++release;
			}
		}
	}
	
	return group->number - release;
}
// 多播的主要处理函数
static int
_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;

	// PTYPE_SYSTEM 协议控制命令
	if (type == PTYPE_SYSTEM) {
		char cmd = '\0';
		uint32_t handle = 0;
		sscanf(msg,"%c %x",&cmd,&handle); // 格式化参数
		if (handle == 0) {
			skynet_error(context, "Invalid handle %s",msg);
			return 0;
		}

		// 简单的命令协议
		switch (cmd) {
		case 'E':
			skynet_multicast_entergroup(g, handle);
			break;
		case 'L':
			skynet_multicast_leavegroup(g, handle);
			break;
		case 'C':
			skynet_command(context, "EXIT", NULL);
			break;
		default:
			skynet_error(context, "Invalid command %s",msg);
			break;
		}
		return 0;		
	}

	// 发送消息出去
	else {
		sz |= type << HANDLE_REMOTE_SHIFT;
		struct skynet_multicast_message * mc = skynet_multicast_create(msg, sz, source);
		skynet_multicast_castgroup(context, g, mc);
		return 1;
	}
}