void EventModule::DoTcpRead(int conn_fd, void* arg) { Epoller* epoller_ = (Epoller*)arg; static char recv_buf[PKG_BUF_SIZE] = {0}; EventModule* event_module = FindModule<EventModule>(App::GetInstance()); void* zmq_sock = event_module->zmq_sock(); ConnMgrModule* conn_mgr_module = FindModule<ConnMgrModule>(App::GetInstance()); Connection* conn = conn_mgr_module->GetConn(conn_fd); if (conn == NULL) { LOG(ERROR) << "GetConn error!"; return; } int32_t recv_len = recv(conn_fd, recv_buf, PKG_BUF_SIZE, 0); if (recv_len < 0) { PLOG(ERROR) << "recv"; conn_mgr_module->ReleaseConn(conn_fd); epoller_->ClearEvent(conn_fd); return; } else if(recv_len == 0) { LOG(INFO) << "client close connection!"; SendConnStop(zmq_sock, conn->player_idx()); conn_mgr_module->ReleaseConn(conn_fd); epoller_->ClearEvent(conn_fd); return; } LOG(INFO) << "-----> recv from client len[" << recv_len << "]"; if (conn->AddRecvData(recv_buf, recv_len) != 0) { LOG(ERROR) << "conn_fd[" << conn_fd << "] over tcp buf"; conn_mgr_module->ReleaseConn(conn_fd); epoller_->ClearEvent(conn_fd); return; } while (conn->IsRecvProtoReady()) { // 接收真实长度大于协议长度就进行处理 int32_t ret = 0; const char* msg_buf = Utils::GetMsgFromClient(conn->recv_buf()); int32_t msg_len = Utils::GetMsgLenFromClient(conn->recv_buf()); static ProtoCs::Msg msg; msg.Clear(); // Protobuf解析 if (msg.ParseFromArray(msg_buf, msg_len) == false) { LOG(ERROR) << "protobuf parse error! msg_len[" << msg_len << "]"; } if (msg_len > PKG_BUF_SIZE) { LOG(ERROR) << "msg_len > PKG_BUF_SIZE"; return; } static ConnData conn_data; if (conn->player_idx() == 0) conn_data.conn_cmd = CONN_START; else conn_data.conn_cmd = CONN_PROC; conn_data.conn_fd = conn_fd; conn_data.player_idx = conn->player_idx(); static char send_buf[PKG_BUF_SIZE + sizeof(conn_data)]; // --- 组包 start --- char* p = send_buf; memcpy(p, &conn_data, sizeof(conn_data)); p += sizeof(conn_data); memcpy(p, msg_buf, msg_len); p += msg_len; int32_t send_len = sizeof(conn_data) + msg_len; // --- 组包 end --- ret = zmq_send(zmq_sock, send_buf, send_len, ZMQ_DONTWAIT); conn->RemoveRecvProto(); LOG(INFO) << "zmq_send ret[" << ret << "]"; if (ret < 0) { LOG(ERROR) << "zmq_send errno[" << errno << "] error[" << strerror(errno) << "]"; conn_mgr_module->ReleaseConn(conn_fd); epoller_->ClearEvent(conn_fd); return; } } }
void MsgModule::Run() { ObjMgrModule* obj_mgr_module = FindModule<ObjMgrModule>(app_); int32_t loop_times = 1000; static char buf[PKG_BUF_SIZE]; int32_t len = 0; while (loop_times--) { // 处理connsvr消息 len = zmq_recv(connsvr_zmq_sock_, buf, 1024, ZMQ_DONTWAIT); if (len > 0) { static ConnData conn_data; memcpy((void*)&conn_data, buf, CONN_DATA_SIZE); const char* msg_buf = Utils::GetMsgFromConn(buf); int32_t msg_len = Utils::GetMsgLenFromConn(len); if (conn_data.conn_cmd == CONN_START) { // 分配内存对象 LOG(INFO) << "CONN_START"; int32_t player_idx = obj_mgr_module->add_player(); Player* player = obj_mgr_module->get_player(player_idx); if (player == NULL) { // 内存池满了 LOG(ERROR) << "create_player error!"; static ProtoCs::Msg msg; msg.Clear(); if (msg.ParseFromArray(msg_buf, msg_len) == false) { LOG(ERROR) << "protobuf parse error!"; return; } int32_t cmd = msg.head().cmd(); if (cmd == ProtoCs::Msg::kLoginReqFieldNumber) { msg.mutable_head()->set_cmd(ProtoCs::Msg::kLoginResFieldNumber); msg.mutable_head()->set_ret(ProtoCs::RET_LOGIN_GAMESVR_FULL); } else if (cmd == ProtoCs::Msg::kQuickRegReqFieldNumber) { msg.mutable_head()->set_cmd(ProtoCs::Msg::kQuickRegResFieldNumber); msg.mutable_head()->set_ret(ProtoCs::RET_QUICK_REG_GAMESVR_FULL); } else if (cmd == ProtoCs::Msg::kNormalRegReqFieldNumber) { msg.mutable_head()->set_cmd(ProtoCs::Msg::kNormalRegResFieldNumber); msg.mutable_head()->set_ret(ProtoCs::RET_NORMAL_REG_GAMESVR_FULL); } SendCloseToConnsvr(&msg, conn_data.conn_fd, 0); return; } conn_data.player_idx = player_idx; player->set_conn_fd(conn_data.conn_fd); } else if (conn_data.conn_cmd == CONN_STOP) { LOG(INFO) << "CONN_STOP"; LOG(INFO) << "player_idx[" << conn_data.player_idx << "] client disconnected"; Player* player = obj_mgr_module->get_player(conn_data.player_idx); if (player != NULL) { LOG(INFO) << "update_player_data"; player->do_update_player_data(); } else { LOG(ERROR) << "update_player_data get_player error"; } obj_mgr_module->del_player(conn_data.player_idx); return; } else if (conn_data.conn_cmd == CONN_PROC) { LOG(INFO) << "CONN_PROC"; } HandleRequest<ProtoCs::Msg>(msg_buf, msg_len, &conn_data); } // 处理datasvr消息 len = zmq_recv(datasvr_zmq_sock_, buf, 1024, ZMQ_DONTWAIT); if (len > 0) { HandleRequest<ProtoSs::Msg>(buf, len, NULL); } } }