void mq_item_destroyer(void *ptr) { msg_t msg = (msg_t)ptr; if(msg->type == MSG_RPACKET) rpk_destroy((rpacket_t*)&msg); else if(msg->type == MSG_WPACKET) wpk_destroy((wpacket_t*)&msg); else { if(MSG_FN_DESTROY(msg)) MSG_FN_DESTROY(msg)(ptr); else free(ptr); } }
int32_t agent_processpacket(msgdisp_t disp,rpacket_t rpk) { uint16_t cmd = rpk_peek_uint16(rpk); if(cmd == CMD_PLY_CONNECTING) { //绑定到asynnet service->msgdisp->bind(service->msgdisp,0,sock,0,30*1000,0);//由系统选择poller }else { if(cmd >= CMD_CLIENT2GATE && cmd < CMD_CLIENT2GATE_END){ rpk_read_uint16(rpk);//丢掉命令码 }else if(cmd >= CMD_GAME2CLIENT && cmd < CMD_GAME2CLIENT_END){ uint16_t size = reverse_read_uint16(rpk);//这个包需要发给多少个客户端 //在栈上创建一个rpacket_t用于读取需要广播的客户端 rpacket_t r = rpk_create_skip(rpk,size*sizeof(agentsession)+sizeof(size)); //将rpk中用于广播的信息丢掉 rpk_dropback(rpk,size*sizeof(agentsession)+sizeof(size)); int i = 0; wpacket_t wpk = wpk_create_by_rpacket(rpk); //发送给所有需要接收的客户端 for( ; i < size; ++i) { agentsession session; session.data = rpk_read_uint32(r); agentplayer_t ply = get_agentplayer(service,session); if(ply) asyn_send(ply->con,wpk); } rpk_destroy(&r); }else{ agentservice_t service = get_thd_agentservice(); sock_ident sock = CAST_2_SOCK(sender); agentsession session; session.data = (uint32_t)asynsock_get_ud(sock); agentplayer_t ply = get_agentplayer(service,session); if(ply && ply->status == agent_playing) { //转发到gameserver send2game(wpk_create_by_rpacket(rpk)); } } } return 1; }
static void dispatch_msg(msgdisp_t disp,msg_t msg) { //printf("dispatch_msg\n"); if(msg->type == MSG_RPACKET) { //printf("RPACKET\n"); rpacket_t rpk = (rpacket_t)msg; if(!disp->process_packet || disp->process_packet(disp,make_by_ident(MSG_IDENT(rpk)),rpk)) rpk_destroy(&rpk); }else if(msg->type == MSG_DB_RESULT){ db_result_t result = (db_result_t)msg; if(result->callback) result->callback(result); free_dbresult(result); }else if(msg->type == MSG_DO_FUNCTION){ msg_do_function_t _msg = (msg_do_function_t)msg; if(_msg->fn_function) _msg->fn_function(MSG_USRPTR(_msg)); free(msg); } else{ struct msg_connection *tmsg = (struct msg_connection*)msg; //printf("dispatch_msg %d\n",msg->type); sock_ident sock = CAST_2_SOCK(tmsg->base._ident); if(msg->type == MSG_ONCONNECT){ //printf("MSG_ONCONNECT\n"); if(disp->on_connect) disp->on_connect(disp,sock,tmsg->ip,tmsg->port); else asynsock_close(sock); } else if(msg->type == MSG_ONCONNECTED){ //printf("MSG_ONCONNECTED\n"); if(disp->on_connected) disp->on_connected(disp,sock,tmsg->ip,tmsg->port); else asynsock_close(sock); } else if(msg->type == MSG_DISCONNECTED && disp->on_disconnect){ disp->on_disconnect(disp,sock,tmsg->ip,tmsg->port,tmsg->reason); } else if(msg->type == MSG_CONNECT_FAIL && disp->connect_failed) disp->connect_failed(disp,tmsg->ip,tmsg->port,tmsg->reason); free(msg); } }
static inline int unpack(struct connection *c) { uint32_t pk_len = 0; uint32_t pk_total_size; rpacket_t r = NULL; do{ if(!c->raw) { if(c->unpack_size <= sizeof(uint32_t)) return 1; buffer_read(c->unpack_buf,c->unpack_pos,(int8_t*)&pk_len,sizeof(pk_len)); pk_total_size = pk_len+sizeof(pk_len); if(pk_total_size > c->unpack_size) return 1; r = rpk_create(c->unpack_buf,c->unpack_pos,pk_len,c->raw); r->base.tstamp = GetSystemSec(); //调整unpack_buf和unpack_pos do{ uint32_t size = c->unpack_buf->size - c->unpack_pos; size = pk_total_size > size ? size:pk_total_size; c->unpack_pos += size; pk_total_size -= size; c->unpack_size -= size; if(c->unpack_pos >= c->unpack_buf->capacity) { /* unpack之前先执行了update_next_recv_pos,在update_next_recv_pos中 * 如果buffer被填满,会扩展一块新的buffer加入链表中,所以这里的 * c->unpack_buf->next不应该会是NULL */ assert(c->unpack_buf->next); c->unpack_pos = 0; c->unpack_buf = buffer_acquire(c->unpack_buf,c->unpack_buf->next); } }while(pk_total_size); } else { pk_len = c->unpack_buf->size - c->unpack_pos; if(!pk_len) return 1; r = rpk_create(c->unpack_buf,c->unpack_pos,pk_len,c->raw); c->unpack_pos += pk_len; c->unpack_size -= pk_len; if(c->unpack_pos >= c->unpack_buf->capacity) { /* unpack之前先执行了update_next_recv_pos,在update_next_recv_pos中 * 如果buffer被填满,会扩展一块新的buffer加入链表中,所以这里的 * c->unpack_buf->next不应该会是NULL */ assert(c->unpack_buf->next); c->unpack_pos = 0; c->unpack_buf = buffer_acquire(c->unpack_buf,c->unpack_buf->next); } } if(r){ int8_t process_ret = 1; if(test_recvable(c->status)) process_ret = c->cb_process_packet(c,r); if(process_ret) rpk_destroy(&r); } if(!test_recvable(c->status)) return 0; }while(1); return 1; }