示例#1
0
void CFileConn::_HandleClientFileStates(CImPdu* pPdu)
{
    // switch state
    // case ready_to_recv
    //     if sender_on
    //       tell sender can_send
    //     else update state
    // case cancel
    //      notify ohter node cancel
    //      close socket
    // case dnoe
    //      notify recver done
    //      close socket

    if (!_IsAuth()) {
		return;
	}
    
    IM::File::IMFileState msg;
    CHECK_PB_PARSE_MSG(msg.ParseFromArray(pPdu->GetBodyData(), pPdu->GetBodyLength()));

    
    string task_id = msg.task_id();
    uint32_t user_id = msg.user_id();
    uint32_t file_stat = msg.state();
    pthread_rwlock_wrlock(&g_file_task_map_lock);
    TaskMap_t::iterator iter = g_file_task_map.find((char*)task_id.c_str());
    if (g_file_task_map.end() == iter) {
        pthread_rwlock_unlock(&g_file_task_map_lock);
        return; // invalid task id
    }
    transfer_task_t* t = iter->second;
    pthread_rwlock_unlock(&g_file_task_map_lock);
    
    t->lock(__LINE__);
    if (t->from_user_id != user_id && t->to_user_id != user_id) {
        log("invalid user_id %d for task %s", user_id, task_id.c_str());
        t->unlock(__LINE__);
        return;
    }
    t->unlock(__LINE__);
    
    switch (file_stat) {
        case IM::BaseDefine::CLIENT_FILE_CANCEL:
        case IM::BaseDefine::CLIENT_FILE_DONE:
        case IM::BaseDefine::CLIENT_FILE_REFUSE:
        {
            // notify other client
            CFileConn* pConn = (CFileConn*)t->GetOpponentConn(user_id);
            pConn->SendPdu(pPdu);
            
            // release
            log("task %s %d by user_id %d notify %d, erased", task_id.c_str(), file_stat, user_id, t->GetOpponent(user_id));
            
            t->self_destroy = true;
            break;
        }
            
        default:
            break;
    }
    
    return;
}
void FileTransferSocket::_fileState(IN std::string& body)
{
	IM::File::IMFileState imFileState;
    if (!imFileState.ParseFromString(body))
    {
        LOG__(ERR, _T("parse failed,body:%s"), util::stringToCString(body));
        return;
    }
	UINT32 nfileState = imFileState.state();

	std::string taskId = imFileState.task_id();
	TransferFileEntity fileEntity;
	if (!TransferFileEntityManager::getInstance()->getFileInfoByTaskId(taskId, fileEntity))
	{
		LOG__(ERR, _T("fileState:can't find the fileInfo "));
		return;
	}

	switch (nfileState)
	{
	case IM::BaseDefine::ClientFileState::CLIENT_FILE_PEER_READY:
		LOG__(APP, _T("fileState--CLIENT_FILE_PEER_READY "));
		break;
	case IM::BaseDefine::ClientFileState::CLIENT_FILE_CANCEL ://取消的了文件传输
		LOG__(APP, _T("fileState--CLIENT_FILE_CANCEL "));
		{
            if (fileEntity.pFileObject)
            {
                delete fileEntity.pFileObject;
                fileEntity.pFileObject = nullptr;
            }
			TransferFileEntityManager::getInstance()->updateFileInfoBysTaskID(fileEntity);
			module::getFileTransferModule()->asynNotifyObserver(module::KEY_FILESEVER_UPLOAD_CANCEL, fileEntity.sTaskID);
		}
		break;
	case IM::BaseDefine::ClientFileState::CLIENT_FILE_REFUSE://拒绝了文件
		LOG__(APP, _T("fileState--CLIENT_FILE_REFUSE "));
		{
            if (fileEntity.pFileObject)
            {
                delete fileEntity.pFileObject;
                fileEntity.pFileObject = nullptr;
            }
			TransferFileEntityManager::getInstance()->updateFileInfoBysTaskID(fileEntity);
			module::getFileTransferModule()->asynNotifyObserver(module::KEY_FILESEVER_UPLOAD_REJECT, fileEntity.sTaskID);
		}
		break;
	case IM::BaseDefine::ClientFileState::CLIENT_FILE_DONE:
		LOG__(APP, _T("fileState--CLIENT_FILE_DONE "));
		if (fileEntity.pFileObject)
		{
			delete fileEntity.pFileObject;
			fileEntity.pFileObject = nullptr;
		}
		TransferFileEntityManager::getInstance()->updateFileInfoBysTaskID(fileEntity);
		module::getFileTransferModule()->asynNotifyObserver(module::KEY_FILESEVER_PROGRESSBAR_FINISHED, fileEntity.sTaskID);
		break;
	default:
		break;
	}
}