bool MTServerAppFramework::on_recv_protocol(SocketHandle socket_handle, Protocol *protocol, bool &detach_protocol) { DefaultProtocolHeader *header = (DefaultProtocolHeader *)protocol->get_protocol_header(); switch(header->get_protocol_type()) { case PROTOCOL_STRING: { StringProtocol* string_protocol = (StringProtocol*)protocol; string &recv_string = string_protocol->get_string(); SLOG_INFO("thread[ID=%d] receive string protocol from fd=%d. receive data:[%s], length=%d", get_thread_id(), socket_handle, recv_string.c_str(), recv_string.size()); StringProtocol* resp_protocol = (StringProtocol*)((DefaultProtocolFamily*)get_protocol_family())->create_protocol(PROTOCOL_STRING); string send_string = "server receive data:"; send_string += recv_string; ((StringProtocol*)resp_protocol)->set_string(send_string); send_protocol(socket_handle, resp_protocol); } break; default: SLOG_WARN("receive undefine protocol. ignore it."); return false; } return false; }
bool MasterServer::on_recv_protocol(SocketHandle socket_handle, Protocol *protocol, bool &detach_protocol) { SFSProtocolFamily* protocol_family = (SFSProtocolFamily*)get_protocol_family(); DefaultProtocolHeader *header = (DefaultProtocolHeader *)protocol->get_protocol_header(); switch(header->get_protocol_type()) { case PROTOCOL_FILE_INFO_REQ: //响应FileInfo请求 { on_file_info_req(socket_handle, protocol); break; } case PROTOCOL_CHUNK_PING: //响应chunk的ping包 { on_chunk_ping(socket_handle, protocol); break; } case PROTOCOL_FILE_INFO: //chunk 上报文件信息 { on_file_info(socket_handle, protocol); break; } default: SLOG_WARN("Thread[ID=%d] fd=%d receive undefined protocol. ignore it.", get_thread_id(), socket_handle); return false; } return true; }
//响应chunk发送file info保存包 void MasterServer::on_file_info(SocketHandle socket_handle, Protocol *protocol) { ProtocolFileInfo *protocol_fileinfo = (ProtocolFileInfo *)protocol; FileInfo &fileinfo = protocol_fileinfo->get_fileinfo(); SLOG_INFO("receive file_info protocol. fd=%d, result=%d, fid=%s.", socket_handle, (int)fileinfo.result, fileinfo.fid.c_str()); if(fileinfo.result != FileInfo::RESULT_SUCC) //chunk保存失败,不需要回复 { SLOG_INFO("chunk save file failed, remove saving task. fid=%s.", fileinfo.fid.c_str()); remove_saving_task(fileinfo.fid); return ; } SFSProtocolFamily* protocol_family = (SFSProtocolFamily*)get_protocol_family(); ProtocolFileInfoSaveResult *protocol_fileinfo_save_result = (ProtocolFileInfoSaveResult *)protocol_family->create_protocol(PROTOCOL_FILE_INFO_SAVE_RESULT); assert(protocol_fileinfo_save_result != NULL); FileInfoSaveResult &save_result = protocol_fileinfo_save_result->get_save_result(); save_result.fid = fileinfo.fid; if(find_saving_task(fileinfo.fid)) //找到正在保存任务 { ChunkPath &chunk_path = fileinfo.get_chunkpath(0); SLOG_INFO("save file info succ: fid=%s, name=%s, size=%d, chunkid=%s, addr=%s, port=%d, index=%d, offset=%d." ,fileinfo.fid.c_str() ,fileinfo.name.c_str() ,fileinfo.size ,chunk_path.id.c_str() ,chunk_path.ip.c_str() ,chunk_path.port ,chunk_path.index ,chunk_path.offset); m_fileinfo_cache.insert(std::make_pair(fileinfo.fid, fileinfo)); save_fileinfo_to_db(fileinfo); remove_saving_task(fileinfo.fid); save_result.result = FileInfoSaveResult::RESULT_SUCC; } else //找不到正在保存的任务 { SLOG_WARN("can't find saving task. fd=%d, fid=%s.", socket_handle, fileinfo.fid.c_str()); save_result.result = FileInfoSaveResult::RESULT_FAILED; } if(!send_protocol(socket_handle, protocol_fileinfo_save_result)) { protocol_family->destroy_protocol(protocol_fileinfo_save_result); SLOG_ERROR("send fileinfo_save_result protocol failed. fd=%d, fid=%s", socket_handle, fileinfo.fid.c_str()); } }
/////////////////////////////////////// MasterServer /////////////////////////////////////// bool MasterServer::start_server() { //Init NetInterface init_net_interface(); set_thread_ready(); ////Add your codes here /////////////////////// m_saving_task_timeout_sec = g_config_reader->GetValueInt("SavingTaskTimeout", 120); //数据库 m_db_connection = NULL; m_db_ip = g_config_reader->GetValueString("DBIP"); m_db_port = g_config_reader->GetValueInt("DBPort", 0); m_db_user = g_config_reader->GetValueString("DBUser"); m_db_passwd = g_config_reader->GetValueString("DBPassword"); m_db_name = g_config_reader->GetValueString("DBName"); if(m_db_ip!="" && m_db_user!="" && m_db_passwd!="" && m_db_name!="") { m_db_connection = new Connection(m_db_name.c_str(), m_db_ip.c_str(), m_db_user.c_str(), m_db_passwd.c_str(), m_db_port); if(!m_db_connection->connected()) { SLOG_ERROR("connect DB error.db=%s, ip=%s, port=%d, user=%s, pwd=%s." ,m_db_name.c_str() ,m_db_ip.c_str() ,m_db_port ,m_db_user.c_str() ,m_db_passwd.c_str()); delete m_db_connection; } } else { SLOG_WARN("DB parameters is invalid. no using DB!!!"); } //注册定时器 IODemuxer *io_demuxer = get_io_demuxer(); assert(io_demuxer != NULL); if(io_demuxer->register_event(-1, EVENT_PERSIST, 3000, this) == -1) { SLOG_ERROR("register timer handler failed."); return false; } io_demuxer->run_loop(); return true; }
bool MasterServer::add_saving_task(const string &fid) { if(find_saving_task(fid)) //已经存在 { SLOG_WARN("saving task[fd=%s] already exists.", fid.c_str()); return true; } TimeFid time_fid; time_fid.insert_time = (int)time(NULL); time_fid.fid = fid; m_time_fid_list.push_front(time_fid); //保存到list头 m_saving_task_map.insert(std::make_pair(fid, m_time_fid_list.begin())); //保存到map SLOG_INFO("add saving task:fid=%s insert_time=%d.", fid.c_str(), time_fid.insert_time); return true; }
bool TaskManager::on_recv_protocol(SocketHandle socket_handle, Protocol *protocol, bool &detach_protocol) { DefaultProtocolHeader *header = (DefaultProtocolHeader *)protocol->get_protocol_header(); switch(header->get_protocol_type()) { case PROTOCOL_RESPOND_SIZE: { RespondSize *temp_protocol = (RespondSize*)protocol; const string file_name = temp_protocol->get_file_name(); unsigned long long file_size = temp_protocol->get_file_size(); SLOG_INFO("receive <RespondSize:file=%s, size=%ld>", file_name.c_str(), file_size); //下载文件 if(file_size > 0) download_task(file_name, file_size); break; } default: SLOG_WARN("receive undefine protocol. ignore it."); break; } return true; }
//响应文件信息查询包 void MasterServer::on_file_info_req(SocketHandle socket_handle, Protocol *protocol) { SFSProtocolFamily* protocol_family = (SFSProtocolFamily*)get_protocol_family(); ProtocolFileInfo *protocol_fileinfo = (ProtocolFileInfo *)protocol_family->create_protocol(PROTOCOL_FILE_INFO); assert(protocol_fileinfo != NULL); ProtocolFileInfoReq *protocol_file_info_req = (ProtocolFileInfoReq *)protocol; const string& fid = protocol_file_info_req->get_fid(); bool query_chunkpath = protocol_file_info_req->get_query_chunkpath(); SLOG_INFO("receive file_info_req protocol.fd=%d, fid=%s, query=%d", socket_handle, fid.c_str(), query_chunkpath?1:0); FileInfo& file_info = protocol_fileinfo->get_fileinfo(); if(get_fileinfo(fid, file_info)) //已经存在 { SLOG_DEBUG("find file_info succ: fid=%s, size=%d.", fid.c_str(), file_info.size); int i; for(i=0; i<file_info.get_chunkpath_count(); ++i) { ChunkPath &chunk_path = file_info.get_chunkpath(i); SLOG_DEBUG("chunk[%d]:id=%s, ip=%s, port=%d, index=%d, offset=%d." ,i, chunk_path.id.c_str(), chunk_path.ip.c_str(), chunk_path.port, chunk_path.index, chunk_path.offset); } file_info.result = FileInfo::RESULT_SUCC; } else if(find_saving_task(fid)) //正在保存 { SLOG_DEBUG("fid=%s is saving.", fid.c_str()); file_info.result = FileInfo::RESULT_SAVING; } else if(query_chunkpath) //分配chunk { file_info.fid = fid; file_info.name = ""; //无效 file_info.size = 0; //无效 ChunkPath chunk_path; ChunkInfo chunk_info; if(get_chunk(chunk_info)) //分配chunk { file_info.result = FileInfo::RESULT_CHUNK; chunk_path.id = chunk_info.id; chunk_path.ip = chunk_info.ip; chunk_path.port = chunk_info.port; chunk_path.index = 0; //无效 chunk_path.offset = 0; //无效 file_info.add_chunkpath(chunk_path); add_saving_task(fid); SLOG_DEBUG("dispatch chunk[id=%s,ip=%s,port=%d] for fid=%s.", chunk_info.id.c_str(), chunk_info.ip.c_str(), chunk_info.port, fid.c_str()); } else { SLOG_WARN("get chunk failed for fid=%s.", fid.c_str()); file_info.result = FileInfo::RESULT_FAILED; } } else //失败 { SLOG_WARN("get file_info failed for fid=%s.", fid.c_str()); file_info.result = FileInfo::RESULT_FAILED; } if(!send_protocol(socket_handle, protocol_fileinfo)) { SLOG_ERROR("send file_info protocol failed. fd=%d, fid=%s.", socket_handle, fid.c_str()); protocol_family->destroy_protocol(protocol_fileinfo); } }