예제 #1
0
static int
_cb(struct skynet_context * ctx, void * ud, int type, int session, uint32_t source, const void * msg, size_t sz) {
	struct gate *g = ud;
	switch(type) {
	case PTYPE_TEXT:
		_ctrl(g , msg , (int)sz);
		break;
	case PTYPE_CLIENT: {
		if (sz <=4 ) {
			skynet_error(ctx, "Invalid client message from %x",source);
			break;
		}
		// The last 4 bytes in msg are the id of socket, write following bytes to it
		const uint8_t * idbuf = msg + sz - 4;
		uint32_t uid = idbuf[0] | idbuf[1] << 8 | idbuf[2] << 16 | idbuf[3] << 24;
		int id = hashid_lookup(&g->hash, uid);
		if (id>=0) {
			// don't send id (last 4 bytes)
			skynet_socket_send(ctx, uid, (void*)msg, sz-4);
			// return 1 means don't free msg
			return 1;
		} else {
			skynet_error(ctx, "Invalid client id %d from %x",(int)uid,source);
			break;
		}
	}
	case PTYPE_SOCKET:
		// recv socket message from skynet_socket
		dispatch_socket_message(g, msg, (int)(sz-sizeof(struct skynet_socket_message)));
		break;
	}
	return 0;
}
예제 #2
0
파일: main.c 프로젝트: brockwell/skynet
static int
_cb(struct skynet_context * ctx, void * ud, int type, int session, uint32_t source, const void * msg, size_t sz) {
	struct gate *g = ud;
	if (type == PTYPE_TEXT) {
		_ctrl(ctx, g , msg , (int)sz);
		return 0;
	}
	assert(type == PTYPE_RESPONSE);
	struct mread_pool * m = g->pool;
	int connection_id = mread_poll(m,100);	// timeout : 100ms
	if (connection_id < 0) {
		skynet_command(ctx, "TIMEOUT", "1");
	} else {
		int id = g->map[connection_id].uid;
		if (id == 0) {
			id = _gen_id(g, connection_id);
			int fd = mread_socket(m , connection_id);
			struct sockaddr_in remote_addr;
			socklen_t len = sizeof(struct sockaddr_in);
			getpeername(fd, (struct sockaddr *)&remote_addr, &len);
			_report(g, ctx, "%d open %d %s:%u",id,fd,inet_ntoa(remote_addr.sin_addr),ntohs(remote_addr.sin_port));
		}
		uint8_t * plen = mread_pull(m,g->header_size);
		if (plen == NULL) {
			if (mread_closed(m)) {
				_remove_id(g,id);
				_report(g, ctx, "%d close", id);
			}
			goto _break;
		}
		// big-endian
		int len ;
		if (g->header_size == 2) {
			len = plen[0] << 8 | plen[1];
		} else {
			len = plen[0] << 24 | plen[1] << 16 | plen[2] << 8 | plen[3];
		}

		void * data = mread_pull(m, len);
		if (data == NULL) {
			if (mread_closed(m)) {
				_remove_id(g,id);
				_report(g, ctx, "%d close", id);
			}
			goto _break;
		}

		_forward(ctx, g, id, data, len);
		mread_yield(m);
_break:
		skynet_command(ctx, "TIMEOUT", "0");
	}
	return 0;
}