Пример #1
0
uint32_t CClientConn::sendMessage(uint32_t nFromId, uint32_t nToId, IM::BaseDefine::MsgType nType, const string& strMsgData)
{
    CImPdu cPdu;
    IM::Message::IMMsgData msg;
    msg.set_from_user_id(nFromId);
    msg.set_to_session_id(nToId);
    msg.set_msg_id(0);
    msg.set_create_time(time(NULL));
    msg.set_msg_type(nType);
    msg.set_msg_data(strMsgData);
    cPdu.SetPBMsg(&msg);
    cPdu.SetServiceId(IM::BaseDefine::SID_MSG);
    cPdu.SetCommandId(IM::BaseDefine::CID_MSG_DATA);
    uint32_t nSeqNo = m_pSeqAlloctor->getSeq(ALLOCTOR_PACKET);
    cPdu.SetSeqNum(nSeqNo);
    SendPdu(&cPdu);
    return nSeqNo;
}
Пример #2
0
    void getUnreadMsgCounter(CImPdu* pPdu, uint32_t conn_uuid)
    {
        IM::Message::IMUnreadMsgCntReq msg;
        IM::Message::IMUnreadMsgCntRsp msgResp;
        if(msg.ParseFromArray(pPdu->GetBodyData(), pPdu->GetBodyLength()))
        {
            CImPdu* pPduResp = new CImPdu;

            uint32_t nUserId = msg.user_id();

            list<IM::BaseDefine::UnreadInfo> lsUnreadCount;
            uint32_t nTotalCnt = 0;
            
            CMessageModel::getInstance()->getUnreadMsgCount(nUserId, nTotalCnt, lsUnreadCount);
            CGroupMessageModel::getInstance()->getUnreadMsgCount(nUserId, nTotalCnt, lsUnreadCount);
            msgResp.set_user_id(nUserId);
            msgResp.set_total_cnt(nTotalCnt);
            for(auto it= lsUnreadCount.begin(); it!=lsUnreadCount.end(); ++it)
            {
                IM::BaseDefine::UnreadInfo* pInfo = msgResp.add_unreadinfo_list();
    //            *pInfo = *it;
                pInfo->set_session_id(it->session_id());
                pInfo->set_session_type(it->session_type());
                pInfo->set_unread_cnt(it->unread_cnt());
                pInfo->set_latest_msg_id(it->latest_msg_id());
                pInfo->set_latest_msg_data(it->latest_msg_data());
                pInfo->set_latest_msg_type(it->latest_msg_type());
                pInfo->set_latest_msg_from_user_id(it->latest_msg_from_user_id());
            }
            
            
            log("userId=%d, unreadCnt=%u, totalCount=%u", nUserId, msgResp.unreadinfo_list_size(), nTotalCnt);
            msgResp.set_attach_data(msg.attach_data());
            pPduResp->SetPBMsg(&msgResp);
            pPduResp->SetSeqNum(pPdu->GetSeqNum());
            pPduResp->SetServiceId(IM::BaseDefine::SID_MSG);
            pPduResp->SetCommandId(IM::BaseDefine::CID_MSG_UNREAD_CNT_RESPONSE);
            CProxyConn::AddResponsePdu(conn_uuid, pPduResp);
        }
        else
        {
            log("parse pb failed");
        }
    }
Пример #3
0
void CImUser::HandleKickUser(CMsgConn* pConn, uint32_t reason)
{
    map<uint32_t, CMsgConn*>::iterator it = m_conn_map.find(pConn->GetHandle());
    if (it != m_conn_map.end()) {
        CMsgConn* pConn = it->second;
        if(pConn) {
            log("kick service user, user_id=%u.", m_user_id);
            IM::Login::IMKickUser msg;
            msg.set_user_id(m_user_id);
            msg.set_kick_reason((::IM::BaseDefine::KickReasonType)reason);
            CImPdu pdu;
            pdu.SetPBMsg(&msg);
            pdu.SetServiceId(SID_LOGIN);
            pdu.SetCommandId(CID_LOGIN_KICK_USER);
            pConn->SendPdu(&pdu);
            pConn->SetKickOff();
            pConn->Close();
        }
    }
}
Пример #4
0
uint32_t ClientConn::login(const string &strName, const string &strPass)
{
    CImPdu cPdu;
    IM::Login::IMLoginReq msg;
    msg.set_user_name(strName);
    msg.set_password(strPass);
    msg.set_online_status(IM::BaseDefine::USER_STATUS_ONLINE);
    msg.set_client_type(IM::BaseDefine::CLIENT_TYPE_WINDOWS);
    msg.set_client_version("100.0.0");
    cPdu.SetPBMsg(&msg);
    cPdu.SetServiceId(IM::BaseDefine::DFFX_SID_LOGIN);
    cPdu.SetCommandId(IM::BaseDefine::DFFX_CID_LOGIN_REQ_USERLOGIN);

	printf("login   %d\n",cPdu.GetCommandId());
	
    uint32_t nSeqNo = m_pSeqAlloctor->getSeq(ALLOCTOR_PACKET);
    cPdu.SetSeqNum(nSeqNo);
    SendPdu(&cPdu);
    return nSeqNo;
}
Пример #5
0
uint32_t ClientConn::getGroupInfo(uint32_t nUserId , const list<IM::BaseDefine::GroupVersionInfo> &lsGroupVersionInfo)
{
	CImPdu cPdu;
	IM::Group::IMGroupInfoListReq msg;
	msg.set_user_id(nUserId);
	
	for(const auto &vi:lsGroupVersionInfo)
	{
		IM::BaseDefine::GroupVersionInfo* pGroupVersionInfo = msg.add_group_version_list();
		pGroupVersionInfo->set_group_id(vi.group_id());
		pGroupVersionInfo->set_version(0);
	}

	cPdu.SetPBMsg(&msg);
    cPdu.SetServiceId(IM::BaseDefine::SID_GROUP);
    cPdu.SetCommandId(IM::BaseDefine::CID_GROUP_INFO_REQUEST);
    uint32_t nSeqNo = m_pSeqAlloctor->getSeq(ALLOCTOR_PACKET);
    cPdu.SetSeqNum(nSeqNo);
    SendPdu(&cPdu);
    return nSeqNo;
}
Пример #6
0
void getChgedDepart(CImPdu* pPdu, uint32_t conn_uuid)
{
    IM::Buddy::IMDepartmentReq msg;
    IM::Buddy::IMDepartmentRsp msgResp;
    if (msg.ParseFromArray(pPdu->GetBodyData(), pPdu->GetBodyLength())) {

        CImPdu* pPduRes = new CImPdu;

        uint32_t nUserId = msg.user_id();
        uint32_t nLastUpdate = msg.latest_update_time();
        list<uint32_t> lsChangedIds;
        CDepartModel::getInstance()->getChgedDeptId(nLastUpdate, lsChangedIds);
        list<IM::BaseDefine::DepartInfo> lsDeparts;
        CDepartModel::getInstance()->getDepts(lsChangedIds, lsDeparts);

        msgResp.set_user_id(nUserId);
        msgResp.set_latest_update_time(nLastUpdate);
        for(auto it=lsDeparts.begin(); it!=lsDeparts.end(); ++it)
        {
            IM::BaseDefine::DepartInfo* pDeptInfo = msgResp.add_dept_list();
            pDeptInfo->set_dept_id(it->dept_id());
            pDeptInfo->set_priority(it->priority());
            pDeptInfo->set_dept_name(it->dept_name());
            pDeptInfo->set_parent_dept_id(it->parent_dept_id());
            pDeptInfo->set_dept_status(it->dept_status());
        }
        log("userId=%u, last_update=%u, cnt=%u", nUserId, nLastUpdate, lsDeparts.size());
        msgResp.set_attach_data(msg.attach_data());
        pPduRes->SetPBMsg(&msgResp);
        pPduRes->SetSeqNum(pPdu->GetSeqNum());
        pPduRes->SetServiceId(IM::BaseDefine::SID_BUDDY_LIST);
        pPduRes->SetCommandId(IM::BaseDefine::CID_BUDDY_LIST_DEPARTMENT_RESPONSE);
        CProxyConn::AddResponsePdu(conn_uuid, pPduRes);

    }
    else
    {
        log("parse pb failed");
    }
}
Пример #7
0
void CLoginConn::OnTimer(uint64_t curr_tick)
{
	if (m_conn_type == LOGIN_CONN_TYPE_CLIENT) {
		if (curr_tick > m_last_recv_tick + CLIENT_TIMEOUT) {
			Close();
		}
	} else {
		if (curr_tick > m_last_send_tick + SERVER_HEARTBEAT_INTERVAL) {
            IM::Other::IMHeartBeat msg;
            CImPdu pdu;
            pdu.SetPBMsg(&msg);
            pdu.SetServiceId(SID_OTHER);
            pdu.SetCommandId(CID_OTHER_HEARTBEAT);
			SendPdu(&pdu);
		}

		if (curr_tick > m_last_recv_tick + SERVER_TIMEOUT) {
			log("connection to MsgServer timeout ");
			Close();
		}
	}
}
Пример #8
0
 /**
  *  设置群组信息推送,屏蔽或者取消屏蔽
  *
  *  @param pPdu      收到的packet包指针
  *  @param conn_uuid 该包过来的socket 描述符
  */
 void setGroupPush(CImPdu* pPdu, uint32_t conn_uuid)
 {
     IM::Group::IMGroupShieldReq msg;
     IM::Group::IMGroupShieldRsp msgResp;
     if(msg.ParseFromArray(pPdu->GetBodyData(), pPdu->GetBodyLength()))
     {
         uint32_t nUserId = msg.user_id();
         uint32_t nGroupId = msg.group_id();
         uint32_t nStatus = msg.shield_status();
         if(CGroupModel::getInstance()->isValidateGroupId(nGroupId))
         {
             
             CImPdu* pPduRes = new CImPdu;
             bool bRet = CGroupModel::getInstance()->setPush(nUserId, nGroupId, IM_GROUP_SETTING_PUSH, nStatus);
             
             msgResp.set_user_id(nUserId);
             msgResp.set_group_id(nGroupId);
             msgResp.set_result_code(bRet?0:1);
         
             log("userId=%u, groupId=%u, result=%u", nUserId, nGroupId, msgResp.result_code());
             
             msgResp.set_attach_data(msg.attach_data());
             pPduRes->SetPBMsg(&msgResp);
             pPduRes->SetSeqNum(pPdu->GetSeqNum());
             pPduRes->SetServiceId(IM::BaseDefine::SID_GROUP);
             pPduRes->SetCommandId(IM::BaseDefine::CID_GROUP_SHIELD_GROUP_RESPONSE);
             CProxyConn::AddResponsePdu(conn_uuid, pPduRes);
         }
         else
         {
             log("Invalid group.userId=%u, groupId=%u", nUserId, nGroupId);
         }
     }
     else
     {
         log("parse pb failed");
     }
 }
Пример #9
0
void CGroupChat::HandleClientGroupCreateRequest(CImPdu* pPdu, CMsgConn* pFromConn)
{
    IM::Group::IMGroupCreateReq msg;
    CHECK_PB_PARSE_MSG(msg.ParseFromArray(pPdu->GetBodyData(), pPdu->GetBodyLength()));

	uint32_t req_user_id = pFromConn->GetUserId();
    string group_name = msg.group_name();
    uint32_t group_type = msg.group_type();
    if (group_type == IM::BaseDefine::GROUP_TYPE_NORMAL) {
        log("HandleClientGroupCreateRequest, create normal group failed, req_id=%u, group_name=%s. ", req_user_id, group_name.c_str());
        return;
    }
	string group_avatar = msg.group_avatar();
	uint32_t user_cnt = msg.member_id_list_size();
	log("HandleClientGroupCreateRequest, req_id=%u, group_name=%s, avatar_url=%s, user_cnt=%u ",
			req_user_id, group_name.c_str(), group_avatar.c_str(), user_cnt);

	CDBServConn* pDbConn = get_db_serv_conn();
	if (pDbConn) {
		CDbAttachData attach_data(ATTACH_TYPE_HANDLE, pFromConn->GetHandle(), 0);
        msg.set_user_id(req_user_id);
        msg.set_attach_data(attach_data.GetBuffer(), attach_data.GetLength());
        pPdu->SetPBMsg(&msg);
		pDbConn->SendPdu(pPdu);
	} else {
		log("no DB connection ");
        IM::Group::IMGroupCreateRsp msg2;
        msg2.set_user_id(req_user_id);
        msg2.set_result_code(1);
        msg2.set_group_name(group_name);
        CImPdu pdu;
        pdu.SetPBMsg(&msg2);
        pdu.SetServiceId(SID_GROUP);
        pdu.SetCommandId(CID_GROUP_CREATE_RESPONSE);
		pdu.SetSeqNum(pPdu->GetSeqNum());
		pFromConn->SendPdu(&pdu);
	}
}
Пример #10
0
void CRouteConn::_HandleUsersStatusRequest(CImPdu* pPdu)
{
    IM::Buddy::IMUsersStatReq msg;
    CHECK_PB_PARSE_MSG(msg.ParseFromArray(pPdu->GetBodyData(), pPdu->GetBodyLength()));

	uint32_t request_id = msg.user_id();
	uint32_t query_count = msg.user_id_list_size();
	log("HandleUserStatusReq, req_id=%u, query_count=%u ", request_id, query_count);

    IM::Buddy::IMUsersStatRsp msg2;
    msg2.set_user_id(request_id);
    msg2.set_attach_data(msg.attach_data());
    list<user_stat_t> result_list;
	user_stat_t status;
    for(uint32_t i = 0; i < query_count; i++)
	{
        IM::BaseDefine::UserStat* user_stat = msg2.add_user_stat_list();
        uint32_t user_id = msg.user_id_list(i);
        user_stat->set_user_id(user_id);
        CUserInfo* pUser = GetUserInfo(user_id);
        if (pUser) {
            user_stat->set_status((::IM::BaseDefine::UserStatType) pUser->GetStatus()) ;
        }
		else
		{
            user_stat->set_status(USER_STATUS_OFFLINE) ;
		}
	}

	// send back query user status
    CImPdu pdu;
    pdu.SetPBMsg(&msg2);
    pdu.SetServiceId(SID_BUDDY_LIST);
    pdu.SetCommandId(CID_BUDDY_LIST_USERS_STATUS_RESPONSE);
	pdu.SetSeqNum(pPdu->GetSeqNum());
	SendPdu(&pdu);
}
Пример #11
0
uint32_t ClientConn::sendMessage(uint32_t nFromId, uint32_t nToId, IM::BaseDefine::MsgType nType, const string& strMsgData)
{
    CImPdu cPdu;
    IM::Message::IMMsgData msg;
    msg.set_from_user_id(nFromId);
    msg.set_to_session_id(nToId);
    msg.set_msg_id(0);
    msg.set_create_time(time(NULL));
    msg.set_msg_type(nType);
	
	//msg.set_msg_data(strMsgData);
	//EncryptMsg
	char * pOutData=NULL;
	uint32_t nOutLen = 0;
	int retCode = EncryptMsg( strMsgData.c_str(), strMsgData.length(), &pOutData, nOutLen);
	if (retCode == 0 && nOutLen > 0 && pOutData != 0)
	{
		msg.set_msg_data( pOutData, nOutLen);
		//delete pOutData;
		Free(pOutData);
		pOutData = NULL;
	}
	else 
	{
		log("EncryptMsg error:%s\n", strMsgData.c_str());
		msg.set_msg_data( strMsgData);
	}
	
    
    cPdu.SetPBMsg(&msg);
    cPdu.SetServiceId(IM::BaseDefine::DFFX_SID_MSG);
    cPdu.SetCommandId(IM::BaseDefine::DFFX_CID_MSG_DATA);
    uint32_t nSeqNo = m_pSeqAlloctor->getSeq(ALLOCTOR_PACKET);
    cPdu.SetSeqNum(nSeqNo);
    SendPdu(&cPdu);
    return nSeqNo;
}
Пример #12
0
void hasOfflineFile(CImPdu* pPdu, uint32_t conn_uuid)
{
    IM::File::IMFileHasOfflineReq msg;
    IM::File::IMFileHasOfflineRsp msgResp;
    if(msg.ParseFromArray(pPdu->GetBodyData(), pPdu->GetBodyLength()))
    {
        CImPdu* pPduRes = new CImPdu;

        uint32_t nUserId = msg.user_id();
        CFileModel* pModel = CFileModel::getInstance();
        list<IM::BaseDefine::OfflineFileInfo> lsOffline;
        pModel->getOfflineFile(nUserId, lsOffline);
        msgResp.set_user_id(nUserId);
        for (list<IM::BaseDefine::OfflineFileInfo>::iterator it=lsOffline.begin();
                it != lsOffline.end(); ++it) {
            IM::BaseDefine::OfflineFileInfo* pInfo = msgResp.add_offline_file_list();
            //            *pInfo = *it;
            pInfo->set_from_user_id(it->from_user_id());
            pInfo->set_task_id(it->task_id());
            pInfo->set_file_name(it->file_name());
            pInfo->set_file_size(it->file_size());
        }

        log("userId=%u, count=%u", nUserId, msgResp.offline_file_list_size());

        msgResp.set_attach_data(msg.attach_data());
        pPduRes->SetPBMsg(&msgResp);
        pPduRes->SetSeqNum(pPdu->GetSeqNum());
        pPduRes->SetServiceId(IM::BaseDefine::SID_FILE);
        pPduRes->SetCommandId(IM::BaseDefine::CID_FILE_HAS_OFFLINE_RES);
        CProxyConn::AddResponsePdu(conn_uuid, pPduRes);
    }
    else
    {
        log("parse pb failed");
    }
}
Пример #13
0
void CGroupChat::HandleGroupInfoResponse(CImPdu* pPdu)
{
    IM::Group::IMGroupInfoListRsp msg;
    CHECK_PB_PARSE_MSG(msg.ParseFromArray(pPdu->GetBodyData(), pPdu->GetBodyLength()));

    uint32_t user_id = msg.user_id();
    uint32_t group_cnt = msg.group_info_list_size();
    CPduAttachData pduAttachData((uchar_t*)msg.attach_data().c_str(), msg.attach_data().length());
    
    log("HandleGroupInfoResponse, user_id=%u, group_cnt=%u. ", user_id, group_cnt);

    //此处是查询成员时使用,主要用于群消息从数据库获得msg_id后进行发送,一般此时group_cnt = 1
    if (pduAttachData.GetPduLength() > 0 && group_cnt > 0)
    {
        IM::BaseDefine::GroupInfo group_info = msg.group_info_list(0);
        uint32_t group_id = group_info.group_id();
        log("GroupInfoRequest is send by server, group_id=%u ", group_id);
        
        std::set<uint32_t> group_member_set;
        for (uint32_t i = 0; i < group_info.group_member_list_size(); i++)
        {
            uint32_t member_user_id = group_info.group_member_list(i);
            group_member_set.insert(member_user_id);
        }
        if (group_member_set.find(user_id) == group_member_set.end())
        {
            log("user_id=%u is not in group, group_id=%u. ", user_id, group_id);
            return;
        }
        
        IM::Message::IMMsgData msg2;
        CHECK_PB_PARSE_MSG(msg2.ParseFromArray(pduAttachData.GetPdu(), pduAttachData.GetPduLength()));
        CImPdu pdu;
        pdu.SetPBMsg(&msg2);
        pdu.SetServiceId(SID_MSG);
        pdu.SetCommandId(CID_MSG_DATA);
        
        //Push相关
        IM::Server::IMGroupGetShieldReq msg3;
        msg3.set_group_id(group_id);
        msg3.set_attach_data(pdu.GetBodyData(), pdu.GetBodyLength());
        for (uint32_t i = 0; i < group_info.group_member_list_size(); i++)
        {
            uint32_t member_user_id = group_info.group_member_list(i);
            
            msg3.add_user_id(member_user_id);
            
            CImUser* pToImUser = CImUserManager::GetInstance()->GetImUserById(member_user_id);
            if (pToImUser)
            {
                CMsgConn* pFromConn = NULL;
                if( member_user_id == user_id )
                {
                    uint32_t reqHandle = pduAttachData.GetHandle();
                    if(reqHandle != 0)
                        pFromConn = CImUserManager::GetInstance()->GetMsgConnByHandle(user_id, reqHandle);
                }
                
                pToImUser->BroadcastData(pdu.GetBuffer(), pdu.GetLength(), pFromConn);
            }
        }
        
        CImPdu pdu2;
        pdu2.SetPBMsg(&msg3);
        pdu2.SetServiceId(SID_OTHER);
        pdu2.SetCommandId(CID_OTHER_GET_SHIELD_REQ);
        CDBServConn* pDbConn = get_db_serv_conn();
        if (pDbConn)
        {
            pDbConn->SendPdu(&pdu2);
        }
    }
    else if (pduAttachData.GetPduLength() == 0)
    {
        //正常获取群信息的返回
        CMsgConn* pConn = CImUserManager::GetInstance()->GetMsgConnByHandle(user_id, pduAttachData.GetHandle());
        if (pConn)
        {
            msg.clear_attach_data();
            pPdu->SetPBMsg(&msg);
            pConn->SendPdu(pPdu);
        }
    }
}
Пример #14
0
void CHttpQuery::_QueryChangeMember(const string& strAppKey, Json::Value &post_json_obj, CHttpConn *pHttpConn)
{
    HTTP::CDBServConn *pConn = HTTP::get_db_serv_conn();
    if (!pConn) {
        log("no connection to RouteServConn ");
        char* response_buf = PackSendResult(HTTP_ERROR_SERVER_EXCEPTION, HTTP_ERROR_MSG[9].c_str());
        pHttpConn->Send(response_buf, (uint32_t)strlen(response_buf));
        pHttpConn->Close();
        return;
    }
    if ( post_json_obj["req_user_id"].isNull()) {
        log("no user id ");
        char* response_buf = PackSendResult(HTTP_ERROR_PARMENT, HTTP_ERROR_MSG[1].c_str());
        pHttpConn->Send(response_buf, (uint32_t)strlen(response_buf));
        pHttpConn->Close();
        return;
    }
    
    if ( post_json_obj["group_id"].isNull() ) {
        log("no group id ");
        char* response_buf = PackSendResult(HTTP_ERROR_PARMENT, HTTP_ERROR_MSG[1].c_str());
        pHttpConn->Send(response_buf, (uint32_t)strlen(response_buf));
        pHttpConn->Close();
        return;
    }
    
    if ( post_json_obj["modify_type"].isNull() ) {
        log("no modify_type ");
        char* response_buf = PackSendResult(HTTP_ERROR_PARMENT, HTTP_ERROR_MSG[1].c_str());
        pHttpConn->Send(response_buf, (uint32_t)strlen(response_buf));
        pHttpConn->Close();
        return;
    }
    
    if (post_json_obj["user_id_list"].isNull()) {
        log("no user list ");
        char* response_buf = PackSendResult(HTTP_ERROR_PARMENT, HTTP_ERROR_MSG[1].c_str());
        pHttpConn->Send(response_buf, (uint32_t)strlen(response_buf));
        pHttpConn->Close();
        return;
    }
    
    try
    {
        uint32_t user_id = post_json_obj["req_user_id"].asUInt();
        uint32_t group_id = post_json_obj["group_id"].asUInt();
        uint32_t modify_type = post_json_obj["modify_type"].asUInt();
        uint32_t user_cnt =  post_json_obj["user_id_list"].size();
        log("QueryChangeMember, user_id: %u, group_id: %u, modify type: %u, user_cnt: %u. ",
            user_id, group_id, modify_type, user_cnt);
        if (!IM::BaseDefine::GroupModifyType_IsValid(modify_type)) {
            log("QueryChangeMember, unvalid modify_type");
            char* response_buf = PackSendResult(HTTP_ERROR_PARMENT, HTTP_ERROR_MSG[1].c_str());
            pHttpConn->Send(response_buf, (uint32_t)strlen(response_buf));
            pHttpConn->Close();
            return;
        }
        CDbAttachData attach_data(ATTACH_TYPE_HANDLE, pHttpConn->GetConnHandle());
        IM::Group::IMGroupChangeMemberReq msg;
        msg.set_user_id(0);
        msg.set_change_type((::IM::BaseDefine::GroupModifyType)modify_type);
        msg.set_group_id(group_id);
        for (uint32_t i = 0; i < user_cnt; i++) {
            uint32_t member_id = post_json_obj["user_id_list"][i].asUInt();
            msg.add_member_id_list(member_id);
        }
        msg.set_attach_data(attach_data.GetBuffer(), attach_data.GetLength());
        CImPdu pdu;
        pdu.SetPBMsg(&msg);
        pdu.SetServiceId(IM::BaseDefine::DFFX_SID_GROUP);
        pdu.SetCommandId(IM::BaseDefine::DFFX_CID_GROUP_CHANGE_MEMBER_REQUEST);
        pConn->SendPdu(&pdu);
    }
    catch (std::runtime_error msg)
    {
        log("parse json data failed.");
        char* response_buf = PackSendResult(HTTP_ERROR_PARMENT, HTTP_ERROR_MSG[1].c_str());
        pHttpConn->Send(response_buf, (uint32_t)strlen(response_buf));
        pHttpConn->Close();
    }
}
Пример #15
0
void CRouteConn::_HandleUserStatusUpdate(CImPdu* pPdu)
{
    IM::Server::IMUserStatusUpdate msg;
    CHECK_PB_PARSE_MSG(msg.ParseFromArray(pPdu->GetBodyData(), pPdu->GetBodyLength()));

	uint32_t user_status = msg.user_status();
	uint32_t user_id = msg.user_id();
    uint32_t client_type = msg.client_type();
	log("HandleUserStatusUpdate, status=%u, uid=%u, client_type=%u ", user_status, user_id, client_type);

	_UpdateUserStatus(user_id, user_status, client_type);
    
    //用于通知客户端,同一用户在pc端的登录情况
    CUserInfo* pUser = GetUserInfo(user_id);
    if (pUser)
    {
        IM::Server::IMServerPCLoginStatusNotify msg2;
        msg2.set_user_id(user_id);
        if (user_status == IM::BaseDefine::USER_STATUS_OFFLINE)
        {
            msg2.set_login_status(IM_PC_LOGIN_STATUS_OFF);
        }
        else
        {
            msg2.set_login_status(IM_PC_LOGIN_STATUS_ON);
        }
        CImPdu pdu;
        pdu.SetPBMsg(&msg2);
        pdu.SetServiceId(SID_OTHER);
        pdu.SetCommandId(CID_OTHER_LOGIN_STATUS_NOTIFY);
        
        if (user_status == USER_STATUS_OFFLINE)
        {
            //pc端下线且无pc端存在,则给msg_server发送一个通知
            if (CHECK_CLIENT_TYPE_PC(client_type) && !pUser->IsPCClientLogin())
            {
                _BroadcastMsg(&pdu);
            }
        }
        else
        {
            //只要pc端在线,则不管上线的是pc还是移动端,都通知msg_server
            if (pUser->IsPCClientLogin())
            {
                _BroadcastMsg(&pdu);
            }
        }
    }
    
    //状态更新的是pc client端,则通知给所有其他人
    if (CHECK_CLIENT_TYPE_PC(client_type))
    {
        IM::Buddy::IMUserStatNotify msg3;
        IM::BaseDefine::UserStat* user_stat = msg3.mutable_user_stat();
        user_stat->set_user_id(user_id);
        user_stat->set_status((IM::BaseDefine::UserStatType)user_status);
        CImPdu pdu2;
        pdu2.SetPBMsg(&msg3);
        pdu2.SetServiceId(SID_BUDDY_LIST);
        pdu2.SetCommandId(CID_BUDDY_LIST_STATUS_NOTIFY);
        
        //用户存在
        if (pUser)
        {
            //如果是pc客户端离线,但是仍然存在pc客户端,则不发送离线通知
            //此种情况一般是pc客户端多点登录时引起
            if (USER_STATUS_OFFLINE == user_status && pUser->IsPCClientLogin())
            {
                return;
            }
            else
            {
                _BroadcastMsg(&pdu2);
            }
        }
        else//该用户不存在了,则表示是离线状态
        {
            _BroadcastMsg(&pdu2);
        }
    }
}
Пример #16
0
/// yunfan add 2014.8.6
void CFileConn::_HandleMsgFileTransferReq(CImPdu* pPdu)
{
    // if realtime transfer
    // new realtime_task
    // generate uuid
    // copy userid_1 userid_2
    // time_t = time(null);
    // return uuid
    // else new offline_task
    // generate uuid
    // copy user_1
    // copy file_size
    // time_t = time(null)
    // return uuid
    
    // create task for:
    // realtime transfer and offline upload
    
    IM::Server::IMFileTransferReq msg;
    CHECK_PB_PARSE_MSG(msg.ParseFromArray(pPdu->GetBodyData(), pPdu->GetBodyLength()));

    
    uint32_t from_id = msg.from_user_id();
    uint32_t to_id = msg.to_user_id();
    
    IM::Server::IMFileTransferRsp msg2;
    msg2.set_result_code(1);
    msg2.set_from_user_id(from_id);
    msg2.set_to_user_id(to_id);
    msg2.set_file_name(msg.file_name());
    msg2.set_file_size(msg.file_size());
    msg2.set_task_id("");
    msg2.set_trans_mode(msg.trans_mode());
    msg2.set_attach_data(msg.attach_data());
    CImPdu pdu;
    pdu.SetPBMsg(&msg2);
    pdu.SetServiceId(SID_OTHER);
    pdu.SetCommandId(CID_OTHER_FILE_TRANSFER_RSP);
    pdu.SetSeqNum(pPdu->GetSeqNum());
    char task_id[64] = {0};
    int iret = generate_id(task_id);
    if (0 > iret || NULL == task_id) {
        SendPdu(&pdu);
        log("create task id failed");
        return; // errno create task id failed 1
    }
    
    // new task and add to task_map
    transfer_task_t* task = new transfer_task_t;
    if (NULL == task) {
        // log new failed
        // return error
        SendPdu(&pdu);
        Close(); // close connection with msg svr
        log("create task failed");
        return; // create task failed
    }
    
    task->transfer_mode = msg.trans_mode();
    task->task_id = task_id;
    task->from_user_id = from_id;
    task->to_user_id = to_id;
    task->file_size = msg.file_size();
    task->create_time = time_t(NULL);

    // read cfg file
    msg2.set_result_code(0);
    pdu.SetPBMsg(&msg2);
	SendPdu(&pdu);
    
    task->create_time = time(NULL);
    pthread_rwlock_wrlock(&g_file_task_map_lock);
    g_file_task_map.insert(make_pair((char*)task->task_id.c_str(), task));
    pthread_rwlock_unlock(&g_file_task_map_lock);
    
    log("create task succeed, task id %s, task type %d, from user %d, to user %d", task->task_id.c_str(), task->transfer_mode, task->from_user_id, task->to_user_id);
    
    return;
}
Пример #17
0
 void getDevicesToken(CImPdu* pPdu, uint32_t conn_uuid)
 {
     IM::Server::IMGetDeviceTokenReq msg;
     IM::Server::IMGetDeviceTokenRsp msgResp;
     if(msg.ParseFromArray(pPdu->GetBodyData(), pPdu->GetBodyLength()))
     {
         CacheManager* pCacheManager = CacheManager::getInstance();
         CacheConn* pCacheConn = pCacheManager->GetCacheConn("token");
         CImPdu* pPduResp = new CImPdu;
         uint32_t nCnt = msg.user_id_size();
         if (pCacheConn)
         {
             vector<string> vecTokens;
             for (uint32_t i=0; i<nCnt; ++i) {
                 string strKey = "device_"+int2string(msg.user_id(i));
                 vecTokens.push_back(strKey);
             }
             map<string, string> mapTokens;
             bool bRet = pCacheConn->mget(vecTokens, mapTokens);
             pCacheManager->RelCacheConn(pCacheConn);
             
             if(bRet)
             {
                 for (auto it=mapTokens.begin(); it!=mapTokens.end(); ++it) {
                     string strKey = it->first;
                     size_t nPos = strKey.find("device_");
                     if( nPos != string::npos)
                     {
                         string strUserId = strKey.substr(nPos + strlen("device_"));
                         uint32_t nUserId = string2int(strUserId);
                         string strValue = it->second;
                         nPos = strValue.find(":");
                         if(nPos!=string::npos)
                         {
                             string strType = strValue.substr(0, nPos);
                             string strToken = strValue.substr(nPos + 1);
                             IM::BaseDefine::ClientType nClientType = IM::BaseDefine::ClientType(0);
                             if(strType == "ios")
                             {
                                 nClientType = IM::BaseDefine::CLIENT_TYPE_IOS;
                             }
                             else if(strType == "android")
                             {
                                 nClientType = IM::BaseDefine::CLIENT_TYPE_ANDROID;
                             }
                             if(IM::BaseDefine::ClientType_IsValid(nClientType))
                             {
                                 IM::BaseDefine::UserTokenInfo* pToken = msgResp.add_user_token_info();
                                 pToken->set_user_id(nUserId);
                                 pToken->set_token(strToken);
                                 pToken->set_user_type(nClientType);
                                 uint32_t nTotalCnt = 0;
                                 CMessageModel::getInstance()->getUnReadCntAll(nUserId, nTotalCnt);
                                 CGroupMessageModel::getInstance()->getUnReadCntAll(nUserId, nTotalCnt);
                                 pToken->set_push_count(nTotalCnt);
                                 pToken->set_push_type(1);
                             }
                             else
                             {
                                 log("invalid clientType.clientType=%u", nClientType);
                             }
                         }
                         else
                         {
                             log("invalid value. value=%s", strValue.c_str());
                         }
                         
                     }
                     else
                     {
                         log("invalid key.key=%s", strKey.c_str());
                     }
                 }
             }
             else
             {
                 log("mget failed!");
             }
         }
         else
         {
             log("no cache connection for token");
         }
         
         log("req devices token.reqCnt=%u, resCnt=%u", nCnt, msgResp.user_token_info_size());
         
         msgResp.set_attach_data(msg.attach_data());
         pPduResp->SetPBMsg(&msgResp);
         pPduResp->SetSeqNum(pPdu->GetSeqNum());
         pPduResp->SetServiceId(IM::BaseDefine::SID_OTHER);
         pPduResp->SetCommandId(IM::BaseDefine::CID_OTHER_GET_DEVICE_TOKEN_RSP);
         CProxyConn::AddResponsePdu(conn_uuid, pPduResp);
     }
     else
     {
         log("parse pb failed");
     }
 }
Пример #18
0
void CDBServConn::_HandleDbRegisterResponse(CImPdu* pPdu)
{
    RUNTIME_TRACE;
    IM::Server::IMDbRegRes msgDb;
    CHECK_PB_PARSE_MSG(msgDb.ParseFromArray(pPdu->GetBodyData(), pPdu->GetBodyLength()));

    string login_name = msgDb.user_name();
    CImUser* pImUser = CImUserManager::GetInstance()->GetImUserByLoginName(login_name);
    if (!pImUser) {
        log("ImUser for user_name=%s not exist", login_name.c_str());
        return;
    }
    
    CDbAttachData attach_data((uchar_t*)msgDb.attach_data().c_str(), msgDb.attach_data().length());

    auto pMsgConn = pImUser->GetUnValidateMsgConn(attach_data.GetHandle());
    if (!pMsgConn || pMsgConn->IsOpen()) {
        log("no such conn, user_name=%s", login_name.c_str());
        return;
    }
    
    IM::BaseDefine::UserInfo user_info = msgDb.user_info();
    uint32_t user_id = user_info.user_id();
    pImUser->SetUserId(user_id);
    pImUser->SetNickName(user_info.user_nick_name());
    pImUser->SetValidated();
    CImUserManager::GetInstance()->AddImUserById(user_id, pImUser);
    
    log("user_name: %s, uid: %d", login_name.c_str(), user_id);
    pMsgConn->SetUserId(user_id);
    pMsgConn->SetOpen();
    pMsgConn->SendUserStatusUpdate(IM::BaseDefine::USER_STATUS_ONLINE);
    pImUser->ValidateMsgConn(pMsgConn->GetHandle(), pMsgConn);
    
    IM::Login::IMRegisterRes msgRes;
    msgRes.set_user_name(login_name);
    msgRes.set_server_time(time(NULL));
    msgRes.set_result_code((IM::BaseDefine::ResultType)msgDb.result_code());
    msgRes.set_online_status((IM::BaseDefine::UserStatType)pMsgConn->GetOnlineStatus());
    msgRes.set_result_string(msgDb.result_string());
    
    IM::BaseDefine::UserInfo* user_info_tmp = msgRes.mutable_user_info();
    user_info_tmp->set_user_id(user_info.user_id());
    user_info_tmp->set_user_gender(user_info.user_gender());
    user_info_tmp->set_user_nick_name(user_info.user_nick_name());
    user_info_tmp->set_avatar_url(user_info.avatar_url());
    user_info_tmp->set_department_id(user_info.department_id());
    user_info_tmp->set_email(user_info.email());
    user_info_tmp->set_user_real_name(user_info.user_real_name());
    user_info_tmp->set_user_tel(user_info.user_tel());
    user_info_tmp->set_user_domain(user_info.user_domain());
    user_info_tmp->set_status(user_info.status());
    CImPdu pdu;
    pdu.SetPBMsg(&msgRes);
    pdu.SetServiceId(SID_LOGIN);
    pdu.SetCommandId(CID_LOGIN_RES_USERREG);
    pdu.SetSeqNum(pPdu->GetSeqNum());
    pMsgConn->SendPdu(&pdu);
    log("send pdu command id = %d", pdu.GetCommandId());
    if (msgDb.result_code())
        pMsgConn->Close();

}
Пример #19
0
void CRouteServConn::_HandleUsersStatusResponse(CImPdu* pPdu)
{
    IM::Buddy::IMUsersStatRsp msg;
    CHECK_PB_PARSE_MSG(msg.ParseFromArray(pPdu->GetBodyData(), pPdu->GetBodyLength()));

	uint32_t user_id = msg.user_id();
	uint32_t result_count = msg.user_stat_list_size();
	log("HandleUsersStatusResp, user_id=%u, query_count=%u ", user_id, result_count);
    
    CPduAttachData attach_data((uchar_t*)msg.attach_data().c_str(), msg.attach_data().length());
    if (attach_data.GetType() == ATTACH_TYPE_HANDLE)
    {
        uint32_t handle = attach_data.GetHandle();
        auto pConn = CImUserManager::GetInstance()->GetMsgConnByHandle(user_id, handle);
        if (pConn) {
            msg.clear_attach_data();
            pPdu->SetPBMsg(&msg);
            pConn->SendPdu(pPdu);
        }
    }
    else if (attach_data.GetType() == ATTACH_TYPE_PDU_FOR_PUSH)
    {
        IM::BaseDefine::UserStat user_stat = msg.user_stat_list(0);
        IM::Server::IMPushToUserReq msg2;
        CHECK_PB_PARSE_MSG(msg2.ParseFromArray(attach_data.GetPdu(), attach_data.GetPduLength()));
        IM::BaseDefine::UserTokenInfo* user_token = msg2.mutable_user_token_list(0);

        //pc client登录,则为勿打扰式推送
        if (user_stat.status() == IM::BaseDefine::USER_STATUS_ONLINE)
        {
            user_token->set_push_type(IM_PUSH_TYPE_SILENT);
            log("HandleUsersStatusResponse, user id: %d, push type: normal. ", user_stat.user_id());
        }
        else
        {
            user_token->set_push_type(IM_PUSH_TYPE_NORMAL);
            log("HandleUsersStatusResponse, user id: %d, push type: normal. ", user_stat.user_id());
        }
        CImPdu pdu;
        pdu.SetPBMsg(&msg2);
        pdu.SetServiceId(SID_OTHER);
        pdu.SetCommandId(CID_OTHER_PUSH_TO_USER_REQ);
        
        auto PushConn = get_push_serv_conn();
        if (PushConn)
        {
            PushConn->SendPdu(&pdu);
        }
    }
    else if (attach_data.GetType() == ATTACH_TYPE_HANDLE_AND_PDU_FOR_FILE)
    {
        IM::BaseDefine::UserStat user_stat = msg.user_stat_list(0);
        IM::Server::IMFileTransferReq msg3;
        CHECK_PB_PARSE_MSG(msg3.ParseFromArray(attach_data.GetPdu(), attach_data.GetPduLength()));
        uint32_t handle = attach_data.GetHandle();
        
        IM::BaseDefine::FileType trans_mode = IM::BaseDefine::FILE_TYPE_OFFLINE;
        if (user_stat.status() == IM::BaseDefine::USER_STATUS_ONLINE)
        {
            trans_mode = IM::BaseDefine::FILE_TYPE_ONLINE;
        }
        msg3.set_trans_mode(trans_mode);
        CImPdu pdu;
        pdu.SetPBMsg(&msg3);
        pdu.SetServiceId(SID_OTHER);
        pdu.SetCommandId(CID_OTHER_FILE_TRANSFER_REQ);
        pdu.SetSeqNum(pPdu->GetSeqNum());
        auto pConn = get_random_file_serv_conn();
        if (pConn) {
            pConn->SendPdu(&pdu);
        }
        else
        {
            log("no file server ");
            IM::File::IMFileRsp msg4;
            msg4.set_result_code(1);
            msg4.set_from_user_id(msg3.from_user_id());
            msg4.set_to_user_id(msg3.to_user_id());
            msg4.set_file_name(msg3.file_name());
            msg4.set_task_id("");
            msg4.set_trans_mode(msg3.trans_mode());
            CImPdu pdu2;
            pdu2.SetPBMsg(&msg4);
            pdu2.SetServiceId(SID_FILE);
            pdu2.SetCommandId(CID_FILE_RESPONSE);
            pdu2.SetSeqNum(pPdu->GetSeqNum());
            auto pMsgConn = CImUserManager::GetInstance()->GetMsgConnByHandle(msg3.from_user_id(),handle);
            if (pMsgConn)
            {
                pMsgConn->SendPdu(&pdu2);
            }
        }
    }
}
Пример #20
0
/// yunfan add 2014.8.7
/// offline file upload
/// file-svr will send pull-data-req to sender
/// then wait for sender's rsp
void* _DoUpload(void* lparam)
{
    if (NULL == lparam) {
        return NULL;
    }
    transfer_task_t* t = reinterpret_cast<transfer_task_t*>(lparam);
    
    t->create_time = time(NULL);
    
    // at begin
    // send 10 data-pull-req
    for (uint32_t cnt = 0; cnt < 1; ++cnt) {
        std::map<uint32_t, upload_package_t*>::iterator iter = t->upload_packages.begin();
        if (t->upload_packages.end() != iter) {
            IM::File::IMFilePullDataReq msg;
            msg.set_task_id(t->task_id);
            msg.set_user_id(t->from_user_id);
            msg.set_trans_mode(::IM::BaseDefine::FILE_TYPE_OFFLINE);
            msg.set_offset(iter->second->offset);
            msg.set_data_size(iter->second->size);
            CImPdu pdu;
            pdu.SetPBMsg(&msg);
            pdu.SetServiceId(SID_FILE);
            pdu.SetCommandId(CID_FILE_PULL_DATA_REQ);
            CFileConn* pConn = (CFileConn*)t->GetConn(t->from_user_id);
            pConn->SendPdu(&pdu);
            log("Pull Data Req");
        }
        ++iter;
    }
    
    // what if there is no rsp?
    // still send req?
    // no!
    // at last, the user will cancel
    // next ver, do change
    while (t->transfered_size != t->upload_packages.size()) {
        if (t->self_destroy) {
        	log("timeout, exit thread, task %s", t->task_id.c_str());
        	return NULL;
        }
        sleep(1);
    }
    

    t->lock(__LINE__);
    
    // write head
    if (NULL == t->file_head) {
        t->file_head = new file_header_t;
    }
    if (NULL == t->file_head) {
        log("create file header failed %s", t->task_id.c_str());
        // beacuse all data in mem
        // it has to be released
        
        /*
        UserMap_t::iterator ator = g_file_user_map.find(t->from_user_id);
        if (g_file_user_map.end() != ator) {
            CFileConn* pConn = (CFileConn*)ator->second;
            pConn->Close();
        }
         */
        CFileConn* pConn = (CFileConn*)t->GetConn(t->from_user_id);
        pConn->Close();
        
        t->self_destroy = true;
        t->unlock(__LINE__);
        return NULL;
        
    }
    t->file_head->set_create_time(time(NULL));
    t->file_head->set_task_id(t->task_id.c_str());
    t->file_head->set_from_user_id(t->from_user_id);
    t->file_head->set_to_user_id(t->to_user_id);
    t->file_head->set_file_name("");
    t->file_head->set_file_size(t->file_size);
    fwrite(t->file_head, 1, sizeof(file_header_t), t->fp);
    
    std::map<uint32_t, upload_package_t*>::iterator itor = t->upload_packages.begin();
    for ( ; itor != t->upload_packages.end(); ++itor) {
        fwrite(itor->second->data, 1, itor->second->size, t->fp);
    }
    
    fflush(t->fp);
    if (t->fp) {
    	fclose(t->fp);
        t->fp = NULL;
    }

    t->unlock(__LINE__);
    return NULL;
}
Пример #21
0
void CLoginConn::_HandleMsgServRequest(CImPdu* pPdu)
{
    IM::Login::IMMsgServReq msg;
    msg.ParseFromArray(pPdu->GetBodyData(), pPdu->GetBodyLength());

	log("HandleMsgServReq. ");

	// no MessageServer available
	if (g_msg_serv_info.size() == 0) {
        IM::Login::IMMsgServRsp msg;
        msg.set_result_code(::IM::BaseDefine::REFUSE_REASON_NO_MSG_SERVER);
        CImPdu pdu;
        pdu.SetPBMsg(&msg);
        pdu.SetServiceId(SID_LOGIN);
        pdu.SetCommandId(CID_LOGIN_RES_MSGSERVER);
        pdu.SetSeqNum(pPdu->GetSeqNum());
        SendPdu(&pdu);
        Close();
		return;
	}

	// return a message server with minimum concurrent connection count
	msg_serv_info_t* pMsgServInfo;
	uint32_t min_user_cnt = (uint32_t)-1;
	map<uint32_t, msg_serv_info_t*>::iterator it_min_conn = g_msg_serv_info.end(),it;

	for (it = g_msg_serv_info.begin() ; it != g_msg_serv_info.end(); it++) {
		pMsgServInfo = it->second;
		if ( (pMsgServInfo->cur_conn_cnt < pMsgServInfo->max_conn_cnt) &&
			 (pMsgServInfo->cur_conn_cnt < min_user_cnt))
        {
			it_min_conn = it;
			min_user_cnt = pMsgServInfo->cur_conn_cnt;
		}
	}

	if (it_min_conn == g_msg_serv_info.end()) {
		log("All TCP MsgServer are full ");
        IM::Login::IMMsgServRsp msg;
        msg.set_result_code(::IM::BaseDefine::REFUSE_REASON_MSG_SERVER_FULL);
        CImPdu pdu;
        pdu.SetPBMsg(&msg);
        pdu.SetServiceId(SID_LOGIN);
        pdu.SetCommandId(CID_LOGIN_RES_MSGSERVER);
        pdu.SetSeqNum(pPdu->GetSeqNum());
        SendPdu(&pdu);
	}
    else
    {
        IM::Login::IMMsgServRsp msg;
        msg.set_result_code(::IM::BaseDefine::REFUSE_REASON_NONE);
        msg.set_prior_ip(it_min_conn->second->ip_addr1);
        msg.set_backip_ip(it_min_conn->second->ip_addr2);
        msg.set_port(it_min_conn->second->port);
        CImPdu pdu;
        pdu.SetPBMsg(&msg);
        pdu.SetServiceId(SID_LOGIN);
        pdu.SetCommandId(CID_LOGIN_RES_MSGSERVER);
        pdu.SetSeqNum(pPdu->GetSeqNum());
        SendPdu(&pdu);
    }

	Close();	// after send MsgServResponse, active close the connection
}
Пример #22
0
void CFileConn::_HandleClientFilePullFileRsp(CImPdu *pPdu)
{
    if (!_IsAuth()) {
		return;
	}
    
    IM::File::IMFilePullDataRsp msg;
    CHECK_PB_PARSE_MSG(msg.ParseFromArray(pPdu->GetBodyData(), pPdu->GetBodyLength()));

	uint32_t user_id = msg.user_id();
    string task_id = msg.task_id();
	uint32_t offset = msg.offset();
	uint32_t data_size = msg.data().length();
    
    pthread_rwlock_wrlock(&g_file_task_map_lock);
    TaskMap_t::iterator iter = g_file_task_map.find(task_id.c_str());
    if (g_file_task_map.end() == iter) {
        // invalid task id
        pthread_rwlock_unlock(&g_file_task_map_lock);
        return;
    }
    transfer_task_t* t = iter->second;
    pthread_rwlock_unlock(&g_file_task_map_lock);
    
    t->lock(__LINE__);
    
    t->create_time = time(NULL);
    
    if (t->from_user_id != user_id && t->to_user_id != user_id) {
        // invalid user
        t->unlock(__LINE__);
        return;
    }
    
    switch (t->transfer_mode) {
        case FILE_TYPE_ONLINE: // transfer request to sender
        {
            CFileConn* pConn = (CFileConn*)t->GetOpponentConn(user_id);
            pConn->SendPdu(pPdu); /// send to recver
            break;
        }
        case FILE_TYPE_OFFLINE: /// this is the response to the server pull-data-req
        {
            if (t->upload_packages.size() <= 0) {
                log("FATAL ERROR");
                t->unlock(__LINE__);
                return;
            }
            
            // check if data size ok
            std::map<uint32_t, upload_package_t*>::iterator itPacks = t->upload_packages.find(offset);
            if (t->upload_packages.end() != itPacks) { // offset right
                
                // check if data size ok
                if (data_size != itPacks->second->size) {
                    // the rsp's data size is different from req's
                    // refuse it or dynamic adjust
                    // do not adjust now, maybe later
                    uint32_t offset = itPacks->second->offset;
                    uint32_t size = itPacks->second->size;
                    // resend req
                    IM::File::IMFilePullDataReq msg2;
                    msg2.set_task_id(task_id);
                    msg2.set_user_id(user_id);
                    msg2.set_trans_mode((::IM::BaseDefine::FileType)t->transfer_mode);
                    msg2.set_offset(offset);
                    msg2.set_data_size(size);
                    CImPdu pdu;
                    pdu.SetPBMsg(&msg2);
                    pdu.SetServiceId(SID_FILE);
                    pdu.SetCommandId(CID_FILE_PULL_DATA_REQ);
                    SendPdu(&pdu);
                    log("size not match");

                    t->unlock(__LINE__);
                    return;
                }
                
                // check if data-ptr OK
                if (NULL == itPacks->second->data) {
                    itPacks->second->data = new char[itPacks->second->size];
                    if (NULL == itPacks->second->data) {
                        uint32_t offset = itPacks->second->offset;
                        uint32_t size = itPacks->second->size;
                        
                        log("alloc mem failed");
                        // resend req
                        IM::File::IMFilePullDataReq msg2;
                        msg2.set_task_id(task_id);
                        msg2.set_user_id(user_id);
                        msg2.set_trans_mode((::IM::BaseDefine::FileType)t->transfer_mode);
                        msg2.set_offset(offset);
                        msg2.set_data_size(size);
                        CImPdu pdu;
                        pdu.SetPBMsg(&msg2);
                        pdu.SetServiceId(SID_FILE);
                        pdu.SetCommandId(CID_FILE_PULL_DATA_REQ);
                        SendPdu(&pdu);
                        t->unlock(__LINE__);
                        return;
                    }
                }
                
                // copy data
                memset(itPacks->second->data, 0,  itPacks->second->size);
                memcpy(itPacks->second->data, msg.data().c_str(), msg.data().length());
                ++t->transfered_size;
            }
            
            // find which segment hasn't got data yet
            bool bFound = false;
            std::map<uint32_t, upload_package_t*>::iterator itor = t->upload_packages.begin();
            for ( ; itor != t->upload_packages.end(); ++itor) {
                if (NULL == itor->second->data) {
                    bFound = true;
                    break;
                }
            }
            if (!bFound) {
                // all packages recved
                _StatesNotify(IM::BaseDefine::CLIENT_FILE_DONE, task_id.c_str(), user_id, t->GetConn(user_id));
                Close();

                t->unlock(__LINE__);
                return;
            }
            // prepare to send req for this segment
            uint32_t next_offset = itor->second->offset;
            uint32_t next_size = itor->second->size;
            
            // send pull-data-req
            IM::File::IMFilePullDataReq msg2;
            msg2.set_task_id(task_id);
            msg2.set_user_id(user_id);
            msg2.set_trans_mode((::IM::BaseDefine::FileType)t->transfer_mode);
            msg2.set_offset(next_offset);
            msg2.set_data_size(next_size);
            CImPdu pdu;
            pdu.SetPBMsg(&msg2);
            pdu.SetServiceId(SID_FILE);
            pdu.SetCommandId(CID_FILE_PULL_DATA_REQ);
            SendPdu(&pdu);
            break;
        }
        default:
            break;
    }
    
    t->unlock(__LINE__);
    return;
}
Пример #23
0
void CFileConn::_HandleClientFilePullFileReq(CImPdu *pPdu)
{
    if (!_IsAuth()) {
		return;
	}
    
    IM::File::IMFilePullDataReq msg;
    CHECK_PB_PARSE_MSG(msg.ParseFromArray(pPdu->GetBodyData(), pPdu->GetBodyLength()));

	uint32_t user_id = msg.user_id();
    string task_id = msg.task_id();
    uint32_t mode = msg.trans_mode();
	uint32_t offset = msg.offset();
	uint32_t datasize = msg.data_size();
    
    IM::File::IMFilePullDataRsp msg2;
    msg2.set_result_code(1);
    msg2.set_task_id(task_id);
    msg2.set_user_id(user_id);
    msg2.set_offset(offset);
    msg2.set_data("");
    CImPdu pdu;
    pdu.SetPBMsg(&msg2);
    pdu.SetServiceId(SID_FILE);
    pdu.SetCommandId(CID_FILE_PULL_DATA_RSP);
    pdu.SetSeqNum(pPdu->GetSeqNum());
    // since the task had been created when the recver logged-in
    // we can find task in g_file_task_map here
    pthread_rwlock_wrlock(&g_file_task_map_lock);
    TaskMap_t::iterator iter = g_file_task_map.find(task_id.c_str());
    if (g_file_task_map.end() == iter) {
        // invalid task id
        pthread_rwlock_unlock(&g_file_task_map_lock);
        log("invalid task id %s ", task_id.c_str());
        SendPdu(&pdu);
        return;
    }
    transfer_task_t* t = iter->second;
    pthread_rwlock_unlock(&g_file_task_map_lock);
    
    t->lock(__LINE__);
    
    t->create_time = time(NULL);
    
    if (t->from_user_id != user_id /*for the realtime recver*/ && t->to_user_id != user_id /*for the offline download*/) {
        // invalid user
        log("illieage user %d for task %s", user_id, task_id.c_str());
        SendPdu(&pdu);
        
        t->unlock(__LINE__);
        return;
    }
    
    switch (mode) {
        case IM::BaseDefine::FILE_TYPE_ONLINE: // transfer request to sender
        {
            CFileConn* pConn = (CFileConn*)t->GetOpponentConn(user_id);
            pConn->SendPdu(pPdu);
            break;
        }
        case IM::BaseDefine::FILE_TYPE_OFFLINE: // for the offline download
        {
            // find file use task id
            // send header info to user
            // send data
            // save path manager not used
            
            // save transfered info into task
            // like FILE*
            // transfered size
            
            
            // haven't been opened
            size_t size = 0;
            if (NULL == t->fp) {
                char save_path[BUFSIZ] = {0};
                snprintf(save_path, BUFSIZ, "%s/%d", g_current_save_path, user_id); // those who can only get files under their user_id-dir
                
                int ret = mkdir(save_path, 0755);
                if ( (ret != 0) && (errno != EEXIST) ) {
                    log("mkdir failed for path: %s", save_path);
                    SendPdu(&pdu);
                    t->unlock(__LINE__);
                    return;
                }
                
                strncat(save_path, "/", BUFSIZ);
                strncat(save_path, task_id.c_str(), BUFSIZ); // use task_id as file name, in case of same-name file
                
                // open at first time
                t->fp = fopen(save_path, "rb");  // save fp
                if (!t->fp) {
                    log("can not open file");
                    SendPdu(&pdu);
                    
                    t->unlock(__LINE__);
                    return;
                }
                
                // read head at open
                if (NULL == t->file_head) {
                    t->file_head = new file_header_t;
                    if (NULL == t->file_head) {
                        // close to ensure next time will new file-header again
                        log("read file head failed.");

                        fclose(t->fp);
                        SendPdu(&pdu);
                        
                        t->unlock(__LINE__);
                        return;
                    }
                }
                
                size = fread(t->file_head, 1, sizeof(file_header_t), t->fp); // read header
                if (sizeof(file_header_t) > size) {
                    // close to ensure next time will read again
                    log("read file head failed.");
                    fclose(t->fp); // error to get header
                    SendPdu(&pdu);
                    
                    t->unlock(__LINE__);
                    return;
                } // the header won't be sent to recver, because the msg svr had already notified it.
                // if the recver needs to check it, it could be helpful
                // or sometime later, the recver needs it in some way.
            }
            
            // read data and send based on offset and datasize.
            char* tmpbuf = new char[datasize];
            if (NULL == tmpbuf) {
                // alloc mem failed
                log("alloc mem failed.");
                SendPdu(&pdu);
                t->unlock(__LINE__);
                return;
            }
            memset(tmpbuf, 0, datasize);
            
            // offset file_header_t
            int iret = fseek(t->fp, sizeof(file_header_t) + offset, SEEK_SET); // read after file_header_t
            if (0 != iret) {
                log("seek offset failed.");
                SendPdu(&pdu);
                delete[] tmpbuf;
                
                t->unlock(__LINE__);
                return;
                // offset failed
            }
            size = fread(tmpbuf, 1, datasize, t->fp);
            msg2.set_data(tmpbuf, size);
            CImPdu pdu2;
            pdu2.SetPBMsg(&msg2);
            pdu2.SetServiceId(SID_FILE);
            pdu2.SetCommandId(CID_FILE_PULL_DATA_RSP);
            pdu2.SetSeqNum(pPdu->GetSeqNum());
            pdu2.SetSeqNum(pPdu->GetSeqNum());
            SendPdu(&pdu2);
            delete[] tmpbuf;
            
            t->transfered_size += size; // record transfered size for next time offset
            if (0 == size) {
                fclose(t->fp);
                t->fp = NULL;
                
                _StatesNotify(CLIENT_FILE_DONE, task_id.c_str(), user_id, this);
                Close();
                
                t->self_destroy = true;
                t->unlock(__LINE__);
                return;
            }
            
            break;
        }
        default:
            break;
    }
  
    t->unlock(__LINE__);
    return;
}
Пример #24
0
void CGroupChat::HandleGroupMessage(CImPdu* pPdu)
{
    IM::Message::IMMsgData msg;
    CHECK_PB_PARSE_MSG(msg.ParseFromArray(pPdu->GetBodyData(), pPdu->GetBodyLength()));
	uint32_t from_user_id = msg.from_user_id();
	uint32_t to_group_id = msg.to_session_id();
	string msg_data = msg.msg_data();
    uint32_t msg_id = msg.msg_id();
    if (msg_id == 0) {
        log("HandleGroupMsg, write db failed, %u->%u. ", from_user_id, to_group_id);
        return;
    }
    uint8_t msg_type = msg.msg_type();
    CDbAttachData attach_data((uchar_t*)msg.attach_data().c_str(), msg.attach_data().length());

    log("HandleGroupMsg, %u->%u, msg id=%u. ", from_user_id, to_group_id, msg_id);

    CMsgConn* pFromConn = CImUserManager::GetInstance()->GetMsgConnByHandle(from_user_id,
                                        attach_data.GetHandle());
    if (pFromConn)
    {
        //接收反馈
        IM::Message::IMMsgDataAck msg2;
        msg2.set_user_id(from_user_id);
        msg2.set_session_id(to_group_id);
        msg2.set_msg_id(msg_id);
        msg2.set_session_type(::IM::BaseDefine::SESSION_TYPE_GROUP);
        CImPdu pdu;
        pdu.SetPBMsg(&msg2);
        pdu.SetServiceId(SID_MSG);
        pdu.SetCommandId(CID_MSG_DATA_ACK);
        pdu.SetSeqNum(pPdu->GetSeqNum());
        pFromConn->SendPdu(&pdu);
    }
    
    CRouteServConn* pRouteConn = get_route_serv_conn();
    if (pRouteConn)
    {
        pRouteConn->SendPdu(pPdu);
    }
    
    // 服务器没有群的信息,向DB服务器请求群信息,并带上消息作为附件,返回时在发送该消息给其他群成员
    //IM::BaseDefine::GroupVersionInfo group_version_info;
    CPduAttachData pduAttachData(ATTACH_TYPE_HANDLE_AND_PDU, attach_data.GetHandle(), pPdu->GetBodyLength(), pPdu->GetBodyData());
    
    IM::Group::IMGroupInfoListReq msg3;
    msg3.set_user_id(from_user_id);
    IM::BaseDefine::GroupVersionInfo* group_version_info = msg3.add_group_version_list();
    group_version_info->set_group_id(to_group_id);
    group_version_info->set_version(0);
    msg3.set_attach_data(pduAttachData.GetBuffer(), pduAttachData.GetLength());
    CImPdu pdu;
    pdu.SetPBMsg(&msg3);
    pdu.SetServiceId(SID_GROUP);
    pdu.SetCommandId(CID_GROUP_INFO_REQUEST);
    CDBServConn* pDbConn = get_db_serv_conn();
    if(pDbConn)
    {
        pDbConn->SendPdu(&pdu);
    }
}
Пример #25
0
void CDBServConn::_HandleValidateResponse(CImPdu* pPdu)
{
    RUNTIME_TRACE;
    IM::Server::IMValidateRsp msg;
    CHECK_PB_PARSE_MSG(msg.ParseFromArray(pPdu->GetBodyData(), pPdu->GetBodyLength()));
    string login_name = msg.user_name();
    uint32_t result = msg.result_code();
    string result_string = msg.result_string();
    CDbAttachData attach_data((uchar_t*)msg.attach_data().c_str(), msg.attach_data().length());
    log("HandleValidateResp, user_name=%s, result=%d", login_name.c_str(), result);
    
    CImUser* pImUser = CImUserManager::GetInstance()->GetImUserByLoginName(login_name);
    SpCMsgConn pMsgConn = NULL;
    if (!pImUser) {
        log("ImUser for user_name=%s not exist", login_name.c_str());
        return;
    } else {
        pMsgConn = pImUser->GetUnValidateMsgConn(attach_data.GetHandle());
        if (!pMsgConn || pMsgConn->IsOpen()) {
            log("no such conn is validated, user_name=%s", login_name.c_str());
            return;
        }
    }
    
    if (result != 0) {
        result = IM::BaseDefine::REFUSE_REASON_DB_VALIDATE_FAILED;
    }
    
    if (result == 0)
    {
        IM::BaseDefine::UserInfo user_info = msg.user_info();
        uint32_t user_id = user_info.user_id();
        CImUser* pUser = CImUserManager::GetInstance()->GetImUserById(user_id);
        if (pUser)
        {
            pUser->AddUnValidateMsgConn(pMsgConn);
            pImUser->DelUnValidateMsgConn(pMsgConn);
            if (pImUser->IsMsgConnEmpty())
            {
                CImUserManager::GetInstance()->RemoveImUserByLoginName(login_name);
                delete pImUser;
            }
        }
        else
        {
            pUser = pImUser;
        }
        
        pUser->SetUserId(user_id);
        pUser->SetNickName(user_info.user_nick_name());
        pUser->SetValidated();
        CImUserManager::GetInstance()->AddImUserById(user_id, pUser);
        
        pUser->KickOutSameClientType(pMsgConn->GetClientType(), IM::BaseDefine::KICK_REASON_DUPLICATE_USER, pMsgConn);
        
        auto pRouteConn = get_route_serv_conn();
        if (pRouteConn) {
            IM::Server::IMServerKickUser msg2;
            msg2.set_user_id(user_id);
            msg2.set_client_type((::IM::BaseDefine::ClientType)pMsgConn->GetClientType());
            msg2.set_reason(1);
            CImPdu pdu;
            pdu.SetPBMsg(&msg2);
            pdu.SetServiceId(SID_OTHER);
            pdu.SetCommandId(CID_OTHER_SERVER_KICK_USER);
            pRouteConn->SendPdu(&pdu);
        }
        
        log("user_name: %s, uid: %d", login_name.c_str(), user_id);
        pMsgConn->SetUserId(user_id);
        pMsgConn->SetOpen();
        pMsgConn->SendUserStatusUpdate(IM::BaseDefine::USER_STATUS_ONLINE);
        pUser->ValidateMsgConn(pMsgConn->GetHandle(), pMsgConn);
        
        IM::Login::IMLoginRes msg3;
        msg3.set_server_time(time(NULL));
        msg3.set_result_code(IM::BaseDefine::REFUSE_REASON_NONE);
        msg3.set_result_string(result_string);
        msg3.set_online_status((IM::BaseDefine::UserStatType)pMsgConn->GetOnlineStatus());
        IM::BaseDefine::UserInfo* user_info_tmp = msg3.mutable_user_info();
        user_info_tmp->set_user_id(user_info.user_id());
        user_info_tmp->set_user_gender(user_info.user_gender());
        user_info_tmp->set_user_nick_name(user_info.user_nick_name());
        user_info_tmp->set_avatar_url(user_info.avatar_url());
        user_info_tmp->set_department_id(user_info.department_id());
        user_info_tmp->set_email(user_info.email());
        user_info_tmp->set_user_real_name(user_info.user_real_name());
        user_info_tmp->set_user_tel(user_info.user_tel());
        user_info_tmp->set_user_domain(user_info.user_domain());
        user_info_tmp->set_status(user_info.status());
        CImPdu pdu2;
        pdu2.SetPBMsg(&msg3);
        pdu2.SetServiceId(SID_LOGIN);
        pdu2.SetCommandId(CID_LOGIN_RES_USERLOGIN);
        pdu2.SetSeqNum(pPdu->GetSeqNum());
        pMsgConn->SendPdu(&pdu2);
    }
    else
    {
        IM::Login::IMLoginRes msg4;
        msg4.set_server_time(time(NULL));
        msg4.set_result_code((IM::BaseDefine::ResultType)result);
        msg4.set_result_string(result_string);
        CImPdu pdu3;
        pdu3.SetPBMsg(&msg4);
        pdu3.SetServiceId(SID_LOGIN);
        pdu3.SetCommandId(CID_LOGIN_RES_USERLOGIN);
        pdu3.SetSeqNum(pPdu->GetSeqNum());
        pMsgConn->SendPdu(&pdu3);
        pMsgConn->Close();
    }
}
Пример #26
0
void CDBServConn::_HandleMsgData(CImPdu *pPdu)
{
    IM::Message::IMMsgData msg;
    CHECK_PB_PARSE_MSG(msg.ParseFromArray(pPdu->GetBodyData(), pPdu->GetBodyLength()));
    if (CHECK_MSG_TYPE_GROUP(msg.msg_type())) {
        s_group_chat->HandleGroupMessage(pPdu);
        return;
    }
    
    uint32_t from_user_id = msg.from_user_id();
    uint32_t to_user_id = msg.to_session_id();
    uint32_t msg_id = msg.msg_id();
    if (msg_id == 0) {
        log("HandleMsgData, write db failed, %u->%u.", from_user_id, to_user_id);
        return;
    }
    
    uint8_t msg_type = msg.msg_type();
    CDbAttachData attach_data((uchar_t*)msg.attach_data().c_str(), msg.attach_data().length());
    uint32_t handle = attach_data.GetHandle();
    
    log("HandleMsgData, from_user_id=%u, to_user_id=%u, msg_id=%u.", from_user_id, to_user_id, msg_id);
    
    SpCMsgConn pMsgConn = CImUserManager::GetInstance()->GetMsgConnByHandle(from_user_id, attach_data.GetHandle());
    if (pMsgConn)
    {
        IM::Message::IMMsgDataAck msg2;
        msg2.set_user_id(from_user_id);
        msg2.set_msg_id(msg_id);
        msg2.set_session_id(to_user_id);
        msg2.set_session_type(::IM::BaseDefine::SESSION_TYPE_SINGLE);
        CImPdu pdu;
        pdu.SetPBMsg(&msg2);
        pdu.SetServiceId(SID_MSG);
        pdu.SetCommandId(CID_MSG_DATA_ACK);
        pdu.SetSeqNum(pPdu->GetSeqNum());
        pMsgConn->SendPdu(&pdu);
    }
    
    auto pRouteConn = get_route_serv_conn();
    if (pRouteConn) {
        pRouteConn->SendPdu(pPdu);
    }
    
    msg.clear_attach_data();
    pPdu->SetPBMsg(&msg);
    CImUser* pFromImUser = CImUserManager::GetInstance()->GetImUserById(from_user_id);
    CImUser* pToImUser = CImUserManager::GetInstance()->GetImUserById(to_user_id);
    pPdu->SetSeqNum(0);
    if (pFromImUser) {
        pFromImUser->BroadcastClientMsgData(pPdu, msg_id, pMsgConn, from_user_id);
    }

    if (pToImUser) {
        pToImUser->BroadcastClientMsgData(pPdu, msg_id, NULL, from_user_id);
    }
    
    IM::Server::IMGetDeviceTokenReq msg3;
    msg3.add_user_id(to_user_id);
    msg3.set_attach_data(pPdu->GetBodyData(), pPdu->GetBodyLength());
    CImPdu pdu2;
    pdu2.SetPBMsg(&msg3);
    pdu2.SetServiceId(SID_OTHER);
    pdu2.SetCommandId(CID_OTHER_GET_DEVICE_TOKEN_REQ);
    SendPdu(&pdu2);
}
Пример #27
0
 void setDevicesToken(CImPdu* pPdu, uint32_t conn_uuid)
 {
     IM::Login::IMDeviceTokenReq msg;
     IM::Login::IMDeviceTokenRsp msgResp;
     if(msg.ParseFromArray(pPdu->GetBodyData(), pPdu->GetBodyLength()))
     {
         uint32_t nUserId = msg.user_id();
         string strToken = msg.device_token();
         CImPdu* pPduResp = new CImPdu;
         CacheManager* pCacheManager = CacheManager::getInstance();
         CacheConn* pCacheConn = pCacheManager->GetCacheConn("token");
         if (pCacheConn)
         {
             IM::BaseDefine::ClientType nClientType = msg.client_type();
             string strValue;
             if(IM::BaseDefine::CLIENT_TYPE_IOS == nClientType)
             {
                 strValue = "ios:"+strToken;
             }
             else if(IM::BaseDefine::CLIENT_TYPE_ANDROID == nClientType)
             {
                 strValue = "android:"+strToken;
             }
             else
             {
                 strValue = strToken;
             }
             
             string strOldValue = pCacheConn->get("device_"+int2string(nUserId));
             
             if(!strOldValue.empty())
             {
                 size_t nPos = strOldValue.find(":");
                 if(nPos!=string::npos)
                 {
                     string strOldToken = strOldValue.substr(nPos + 1);
                     string strReply = pCacheConn->get("device_"+strOldToken);
                     if (!strReply.empty()) {
                         string strNewValue("");
                         pCacheConn->set("device_"+strOldToken, strNewValue);
                     }
                 }
             }
             
             pCacheConn->set("device_"+int2string(nUserId), strValue);
             string strNewValue = int2string(nUserId);
             pCacheConn->set("device_"+strToken, strNewValue);
         
             log("setDeviceToken. userId=%u, deviceToken=%s", nUserId, strToken.c_str());
             pCacheManager->RelCacheConn(pCacheConn);
         }
         else
         {
             log("no cache connection for token");
         }
         
         log("setDeviceToken. userId=%u, deviceToken=%s", nUserId, strToken.c_str());
         msgResp.set_attach_data(msg.attach_data());
         msgResp.set_user_id(nUserId);
         pPduResp->SetPBMsg(&msgResp);
         pPduResp->SetSeqNum(pPdu->GetSeqNum());
         pPduResp->SetServiceId(IM::BaseDefine::SID_LOGIN);
         pPduResp->SetCommandId(IM::BaseDefine::CID_LOGIN_RES_DEVICETOKEN);
         CProxyConn::AddResponsePdu(conn_uuid, pPduResp);
     }
     else
     {
         log("parse pb failed");
     }
 }
Пример #28
0
void CDBServConn::_HandleGetDeviceTokenResponse(CImPdu *pPdu)
{
    IM::Server::IMGetDeviceTokenRsp msg;
    CHECK_PB_PARSE_MSG(msg.ParseFromArray(pPdu->GetBodyData(), pPdu->GetBodyLength()));
    
    IM::Message::IMMsgData msg2;
    CHECK_PB_PARSE_MSG(msg2.ParseFromArray(msg.attach_data().c_str(), msg.attach_data().length()));
    string msg_data = msg2.msg_data();
    uint32_t msg_type = msg2.msg_type();
    uint32_t from_id = msg2.from_user_id();
    uint32_t to_id = msg2.to_session_id();
    if (msg_type == IM::BaseDefine::MSG_TYPE_SINGLE_TEXT || msg_type == IM::BaseDefine::MSG_TYPE_GROUP_TEXT)
    {
        //msg_data =
        char* msg_out = NULL;
        uint32_t msg_out_len = 0;
        if (pAes->Decrypt(msg_data.c_str(), msg_data.length(), &msg_out, msg_out_len) == 0)
        {
            msg_data = string(msg_out, msg_out_len);
        }
        else
        {
            log("HandleGetDeviceTokenResponse, decrypt msg failed, from_id: %u, to_id: %u, msg_type: %u.", from_id, to_id, msg_type);
            return;
        }
        pAes->Free(msg_out);
    }
    
    build_ios_push_flash(msg_data, msg2.msg_type(), from_id);
    //{
    //    "msg_type": 1,
    //    "from_id": "1345232",
    //    "group_type": "12353",
    //}
    jsonxx::Object json_obj;
    json_obj << "msg_type" << (uint32_t)msg2.msg_type();
    json_obj << "from_id" << from_id;
    if (CHECK_MSG_TYPE_GROUP(msg2.msg_type())) {
        json_obj << "group_id" << to_id;
    }
    
    uint32_t user_token_cnt = msg.user_token_info_size();
    log("HandleGetDeviceTokenResponse, user_token_cnt = %u.", user_token_cnt);
    
    IM::Server::IMPushToUserReq msg3;
    for (uint32_t i = 0; i < user_token_cnt; i++)
    {
        IM::BaseDefine::UserTokenInfo user_token = msg.user_token_info(i);
        uint32_t user_id = user_token.user_id();
        string device_token = user_token.token();
        uint32_t push_cnt = user_token.push_count();
        uint32_t client_type = user_token.user_type();
        //自己发得消息不给自己发推送
        if (from_id == user_id) {
            continue;
        }
        
        log("HandleGetDeviceTokenResponse, user_id = %u, device_token = %s, push_cnt = %u, client_type = %u.",
            user_id, device_token.c_str(), push_cnt, client_type);
        
        CImUser* pUser = CImUserManager::GetInstance()->GetImUserById(user_id);
        if (pUser)
        {
            msg3.set_flash(msg_data);
            msg3.set_data(json_obj.json());
            IM::BaseDefine::UserTokenInfo* user_token_tmp = msg3.add_user_token_list();
            user_token_tmp->set_user_id(user_id);
            user_token_tmp->set_user_type((IM::BaseDefine::ClientType)client_type);
            user_token_tmp->set_token(device_token);
            user_token_tmp->set_push_count(push_cnt);
            //pc client登录,则为勿打扰式推送
            if (pUser->GetPCLoginStatus() == IM_PC_LOGIN_STATUS_ON)
            {
                user_token_tmp->set_push_type(IM_PUSH_TYPE_SILENT);
                log("HandleGetDeviceTokenResponse, user id: %d, push type: silent.", user_id);
            }
            else
            {
                user_token_tmp->set_push_type(IM_PUSH_TYPE_NORMAL);
                log("HandleGetDeviceTokenResponse, user id: %d, push type: normal.", user_id);
            }
        }
        else
        {
            IM::Server::IMPushToUserReq msg4;
            msg4.set_flash(msg_data);
            msg4.set_data(json_obj.json());
            IM::BaseDefine::UserTokenInfo* user_token_tmp = msg4.add_user_token_list();
            user_token_tmp->set_user_id(user_id);
            user_token_tmp->set_user_type((IM::BaseDefine::ClientType)client_type);
            user_token_tmp->set_token(device_token);
            user_token_tmp->set_push_count(push_cnt);
            user_token_tmp->set_push_type(IM_PUSH_TYPE_NORMAL);
            CImPdu pdu;
            pdu.SetPBMsg(&msg4);
            pdu.SetServiceId(SID_OTHER);
            pdu.SetCommandId(CID_OTHER_PUSH_TO_USER_REQ);
            
            CPduAttachData attach_data(ATTACH_TYPE_PDU_FOR_PUSH, 0, pdu.GetBodyLength(), pdu.GetBodyData());
            IM::Buddy::IMUsersStatReq msg5;
            msg5.set_user_id(0);
            msg5.add_user_id_list(user_id);
            msg5.set_attach_data(attach_data.GetBuffer(), attach_data.GetLength());
            CImPdu pdu2;
            pdu2.SetPBMsg(&msg5);
            pdu2.SetServiceId(SID_BUDDY_LIST);
            pdu2.SetCommandId(CID_BUDDY_LIST_USERS_STATUS_REQUEST);
            auto route_conn = get_route_serv_conn();
            if (route_conn)
            {
                route_conn->SendPdu(&pdu2);
            }
        }
    }
    
    if (msg3.user_token_list_size() > 0)
    {
        CImPdu pdu3;
        pdu3.SetPBMsg(&msg3);
        pdu3.SetServiceId(SID_OTHER);
        pdu3.SetCommandId(CID_OTHER_PUSH_TO_USER_REQ);
        
        auto PushConn = get_push_serv_conn();
        if (PushConn) {
            PushConn->SendPdu(&pdu3);
        }
    }
}
Пример #29
0
void doLogin(CImPdu* pPdu, uint32_t conn_uuid)
{
    
    CImPdu* pPduResp = new CImPdu;
    
    IM::Server::IMValidateReq msg;
    IM::Server::IMValidateRsp msgResp;
    if(msg.ParseFromArray(pPdu->GetBodyData(), pPdu->GetBodyLength()))
    {
        
        string strDomain = msg.user_name();
        string strPass = msg.password();
        
        msgResp.set_user_name(strDomain);
        msgResp.set_attach_data(msg.attach_data());
        
        do
        {
            CAutoLock cAutoLock(&g_cLimitLock);
            list<uint32_t>& lsErrorTime = g_hmLimits[strDomain];
            uint32_t tmNow = time(NULL);
            
            //清理超过30分钟的错误时间点记录
            /*
             清理放在这里还是放在密码错误后添加的时候呢?
             放在这里,每次都要遍历,会有一点点性能的损失。
             放在后面,可能会造成30分钟之前有10次错的,但是本次是对的就没办法再访问了。
             */
            auto itTime=lsErrorTime.begin();
            for(; itTime!=lsErrorTime.end();++itTime)
            {
                if(tmNow - *itTime > 30*60)
                {
                    break;
                }
            }
            if(itTime != lsErrorTime.end())
            {
                lsErrorTime.erase(itTime, lsErrorTime.end());
            }
            
            // 判断30分钟内密码错误次数是否大于10
            if(lsErrorTime.size() > 10)
            {
                itTime = lsErrorTime.begin();
                if(tmNow - *itTime <= 30*60)
                {
                    msgResp.set_result_code(6);
                    msgResp.set_result_string("用户名/密码错误次数太多");
                    pPduResp->SetPBMsg(&msgResp);
                    pPduResp->SetSeqNum(pPdu->GetSeqNum());
                    pPduResp->SetServiceId(IM::BaseDefine::SID_OTHER);
                    pPduResp->SetCommandId(IM::BaseDefine::CID_OTHER_VALIDATE_RSP);
                    CProxyConn::AddResponsePdu(conn_uuid, pPduResp);
                    return ;
                }
            }
        } while(false);
        
        log("%s request login.", strDomain.c_str());
        
        
        
        IM::BaseDefine::UserInfo cUser;
        
        if(g_loginStrategy.doLogin(strDomain, strPass, cUser))
        {
            IM::BaseDefine::UserInfo* pUser = msgResp.mutable_user_info();
            pUser->set_user_id(cUser.user_id());
            pUser->set_user_gender(cUser.user_gender());
            pUser->set_department_id(cUser.department_id());
            pUser->set_user_nick_name(cUser.user_nick_name());
            pUser->set_user_domain(cUser.user_domain());
            pUser->set_avatar_url(cUser.avatar_url());
            
            pUser->set_email(cUser.email());
            pUser->set_user_tel(cUser.user_tel());
            pUser->set_user_real_name(cUser.user_real_name());
            pUser->set_status(0);

            pUser->set_sign_info(cUser.sign_info());
           
            msgResp.set_result_code(0);
            msgResp.set_result_string("成功");
            
            //如果登陆成功,则清除错误尝试限制
            CAutoLock cAutoLock(&g_cLimitLock);
            list<uint32_t>& lsErrorTime = g_hmLimits[strDomain];
            lsErrorTime.clear();
        }
        else
        {
            //密码错误,记录一次登陆失败
            uint32_t tmCurrent = time(NULL);
            CAutoLock cAutoLock(&g_cLimitLock);
            list<uint32_t>& lsErrorTime = g_hmLimits[strDomain];
            lsErrorTime.push_front(tmCurrent);
            
            log("get result false");
            msgResp.set_result_code(1);
            msgResp.set_result_string("用户名/密码错误");
        }
    }
    else
    {
        msgResp.set_result_code(2);
        msgResp.set_result_string("服务端内部错误");
    }
    
    
    pPduResp->SetPBMsg(&msgResp);
    pPduResp->SetSeqNum(pPdu->GetSeqNum());
    pPduResp->SetServiceId(IM::BaseDefine::SID_OTHER);
    pPduResp->SetCommandId(IM::BaseDefine::CID_OTHER_VALIDATE_RSP);
    CProxyConn::AddResponsePdu(conn_uuid, pPduResp);
}
Пример #30
0
void CFileConn::_HandleClientFileLoginReq(CImPdu* pPdu)
{
    // if can not find uuid
    // return invalid uuid
    // if invalid user_id
    // return invalid user
    
    // if ready_to_recv or offline / mobile task
    //   return can_send
    // return ok
    IM::File::IMFileLoginReq msg;
    CHECK_PB_PARSE_MSG(msg.ParseFromArray(pPdu->GetBodyData(), pPdu->GetBodyLength()));
    uint32_t user_id = msg.user_id();
    string task_id = msg.task_id();
    IM::BaseDefine::ClientFileRole mode = msg.file_role();

	m_user_id = user_id;
	log("client login, user_id=%u, handle %d", m_user_id, m_handle);

    // auth done
    m_bAuth = true;
    m_conntype = CONN_TYPE_CLIENT;
    
    IM::File::IMFileLoginRsp msg2;
    msg2.set_result_code(1);
    msg2.set_task_id(task_id);
    CImPdu pdu;
    pdu.SetPBMsg(&msg2);
    pdu.SetServiceId(SID_FILE);
    pdu.SetCommandId(CID_FILE_LOGIN_RES);
    pdu.SetSeqNum(pPdu->GetSeqNum());
    
    // create task for offline download
    if (IM::BaseDefine::CLIENT_OFFLINE_DOWNLOAD == mode) {
        // create a thread // insert into a queue, multi-threads handle the queue
        // find file
        // send file
        transfer_task_t* t = new transfer_task_t;
        if (NULL == t) {
            SendPdu(&pdu);
            Close();
            log("create task failed for task id %s, user %d", task_id.c_str(), m_user_id);
            return; // create task failed
        }
        t->task_id = task_id;
        t->to_user_id = m_user_id;
        t->create_time = time(NULL);
        pthread_rwlock_wrlock(&g_file_task_map_lock);
        g_file_task_map.insert(std::make_pair(task_id.c_str(), t));
        pthread_rwlock_unlock(&g_file_task_map_lock);
    }
    
    // check task
    pthread_rwlock_wrlock(&g_file_task_map_lock);
    TaskMap_t::iterator iter = g_file_task_map.find(task_id.c_str());
    if (g_file_task_map.end() == iter) {
        // failed to find task
        // return invaild task id
        pthread_rwlock_unlock(&g_file_task_map_lock);
        SendPdu(&pdu);
        Close(); // invalid user for task
        log("check task id failed, user_id = %u, request taks id %s", m_user_id, task_id.c_str());
        return;
    }
    transfer_task_t* t = iter->second;
    pthread_rwlock_unlock(&g_file_task_map_lock);
    
    // check user
    if (t->from_user_id != m_user_id && t->to_user_id != m_user_id) {
        // invalid user
        // return error
        SendPdu(&pdu);
        Close();
        log("invalid user %u for task %s", m_user_id, task_id.c_str());
        return;
    }
    
    // prepare for offline upload
    if (CLIENT_OFFLINE_UPLOAD == mode) {
        int iret = _PreUpload(task_id.c_str());
        if (0 > iret) {
            SendPdu(&pdu);
            Close();
            log("preload faild for task %s, err %d", task_id.c_str(), iret);
            return;
        }
    }
    
    if (t->from_user_id == m_user_id) {
        t->from_conn = this;
    }
    if (t->to_user_id == m_user_id) {
        t->to_conn = this;
    }
    
    // send result
    msg2.set_result_code(0);
    CImPdu pdu2;
    pdu2.SetPBMsg(&msg2);
    pdu2.SetServiceId(SID_FILE);
    pdu2.SetCommandId(CID_FILE_LOGIN_RES);
    pdu2.SetSeqNum(pPdu->GetSeqNum());
	SendPdu(&pdu2); // login succeed
    
    /// yunfan add 2014.8.12
    // 2014.8.14
    // record state
    if (m_user_id == t->from_user_id) {
        t->ready_to_send = true;
    }
    if (m_user_id == t->to_user_id) {
        t->ready_to_recv = true;
    }
    // notify that the peet is ready
    if ( (m_user_id == t->to_user_id && \
          t->ready_to_send) || \
        (m_user_id == t->from_user_id && \
         t->ready_to_recv)){
        // send peer-ready state to recver
        _StatesNotify(IM::BaseDefine::CLIENT_FILE_PEER_READY, task_id.c_str(), m_user_id, t->GetConn(m_user_id));
        log("nofity recver %d task %s can recv", m_user_id, task_id.c_str());
    }
    
    // create a thread // insert into a queue, multi-threads handle the queue
    // send to client PULLDATA msg
    // recv and write file
    if (IM::BaseDefine::CLIENT_OFFLINE_UPLOAD == mode) {
        // check thread id
        pthread_create(&t->worker, NULL, _DoUpload, t);
        log("create thread for offline upload task %s user %d thread id %d", task_id.c_str(), m_user_id, t->worker);
    }
    /// yunfan add end

    return;
}