Esempio n. 1
0
void update_master_route_serv_conn()
{
	uint64_t oldest_connect_time = (uint64_t)-1;
	CRouteServConn* pOldestConn = NULL;

	CRouteServConn* pConn = NULL;

	for (uint32_t i = 0; i < g_route_server_count; i++) {
		pConn = (CRouteServConn*)g_route_server_list[i].serv_conn;
		if (pConn && pConn->IsOpen() && (pConn->GetConnectTime() < oldest_connect_time) ){
			pOldestConn = pConn;
			oldest_connect_time = pConn->GetConnectTime();
		}
	}

	g_master_rs_conn =  pOldestConn;

	if (g_master_rs_conn) {
        IM::Server::IMRoleSet msg;
        msg.set_master(1);
        CImPdu pdu;
        pdu.SetPBMsg(&msg);
        pdu.SetServiceId(SID_OTHER);
        pdu.SetCommandId(CID_OTHER_ROLE_SET);
		g_master_rs_conn->SendPdu(&pdu);
	}
}
Esempio n. 2
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);
    
    CMsgConn* 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);

        pMsgConn->SendPdu(SID_MSG, CID_MSG_DATA_ACK, msg2);
    }
    
    CRouteServConn* 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());

    SendPdu(SID_OTHER, CID_OTHER_GET_DEVICE_TOKEN_REQ, msg3);
}
Esempio n. 3
0
void send_to_all_route_server(CImPdu* pPdu)
{
	CRouteServConn* pConn = NULL;

	for (uint32_t i = 0; i < g_route_server_count; i++) {
		pConn = (CRouteServConn*)g_route_server_list[i].serv_conn;
		if (pConn && pConn->IsOpen()) {
			pConn->SendPdu(pPdu);
		}
	}
}
Esempio n. 4
0
void CGroupChat::HandleGroupChangeMemberResponse(CImPdu* pPdu)
{
    IM::Group::IMGroupChangeMemberRsp msg;
    CHECK_PB_PARSE_MSG(msg.ParseFromArray(pPdu->GetBodyData(), pPdu->GetBodyLength()));

    uint32_t change_type = msg.change_type();
	uint32_t user_id = msg.user_id();
	uint32_t result = msg.result_code();
	uint32_t group_id = msg.group_id();
	uint32_t chg_user_cnt = msg.chg_user_id_list_size();
    uint32_t cur_user_cnt = msg.cur_user_id_list_size();
	log("HandleChangeMemberResp, change_type=%u, req_id=%u, group_id=%u, result=%u, chg_usr_cnt=%u, cur_user_cnt=%u. ",
			change_type, user_id, group_id, result, chg_user_cnt, cur_user_cnt);

    CDbAttachData attach_data((uchar_t*)msg.attach_data().c_str(), msg.attach_data().length());
    CMsgConn* pFromConn = CImUserManager::GetInstance()->GetMsgConnByHandle(user_id,
                                                                attach_data.GetHandle());
    if (pFromConn) {
        msg.clear_attach_data();
        pPdu->SetPBMsg(&msg);
        pFromConn->SendPdu(pPdu);
    }
   
	if (!result) {
        IM::Group::IMGroupChangeMemberNotify msg2;
        msg2.set_user_id(user_id);
        msg2.set_change_type((::IM::BaseDefine::GroupModifyType)change_type);
        msg2.set_group_id(group_id);
        for (uint32_t i = 0; i < chg_user_cnt; i++) {
            msg2.add_chg_user_id_list(msg.chg_user_id_list(i));
        }
        for (uint32_t i = 0; i < cur_user_cnt; i++) {
            msg2.add_cur_user_id_list(msg.cur_user_id_list(i));
        }
        CImPdu pdu;
        pdu.SetPBMsg(&msg2);
        pdu.SetServiceId(SID_GROUP);
        pdu.SetCommandId(CID_GROUP_CHANGE_MEMBER_NOTIFY);
		CRouteServConn* pRouteConn = get_route_serv_conn();
		if (pRouteConn) {
			pRouteConn->SendPdu(&pdu);
		}

        for (uint32_t i = 0; i < chg_user_cnt; i++)
        {
            uint32_t to_user_id = msg.chg_user_id_list(i);
            _SendPduToUser(&pdu, to_user_id, pFromConn);
        }
        for (uint32_t i = 0; i < cur_user_cnt; i++) {
            uint32_t to_user_id = msg.cur_user_id_list(i);
            _SendPduToUser(&pdu, to_user_id, pFromConn);
        }
    }
}
Esempio n. 5
0
bool is_route_server_available()
{
	CRouteServConn* pConn = NULL;

	for (uint32_t i = 0; i < g_route_server_count; i++) {
		pConn = (CRouteServConn*)g_route_server_list[i].serv_conn;
		if (pConn && pConn->IsOpen()) {
			return true;
		}
	}

	return false;
}
Esempio n. 6
0
void CFileHandler::HandleClientFileRequest(CMsgConn* pMsgConn, CImPduClientFileRequest* pPdu)
{
	string from_id_url(pPdu->GetFromId(), pPdu->GetFromIdLen());
	uint32_t from_id = urltoid(from_id_url.c_str());
	string to_id_url(pPdu->GetToId(), pPdu->GetToIdLen());
	uint32_t to_id = urltoid(to_id_url.c_str());
	string file_name(pPdu->GetFileName(), pPdu->GetFileNameLen());
	uint32_t file_size = pPdu->GetFileSize();
	log("HandleClientFileRequest, %u->%u, fileName: %s\n", from_id, to_id, file_name.c_str());

    CPduAttachData attach(ATTACH_TYPE_HANDLE, pMsgConn->GetHandle(), 0, NULL, 0);

    CImUser* pUser = CImUserManager::GetInstance()->GetImUserById(to_id);
    if (pUser)
    {
        uint32_t client_type_flag = pUser->GetClientTypeFlag();
        //to_user has pc_client in this msg_server
        if ((client_type_flag & CLIENT_TYPE_FLAG_BOTH) == CLIENT_TYPE_FLAG_PC)
        {
            CFileServConn* pFileConn = get_random_file_serv_conn();
            if (pFileConn)
            {
                CImPduMsgFileTransferReq pdu(from_id, to_id, file_name.c_str(), file_size,
                                    FILE_TYPE_ONLINE, attach.GetLength(), attach.GetBuffer());
                pdu.SetReserved(pPdu->GetReserved());
                pFileConn->SendPdu(&pdu);
            }
            else
            {
                log("HandleClientFileRequest, no file server.\n");
                CImPduClientFileResponse pdu2(REFUSE_REASON_NO_FILE_SERVER, from_id_url.c_str(),
                                              to_id_url.c_str(), file_name.c_str(), NULL, NULL, 0);
                pdu2.SetReserved(pPdu->GetReserved());
                pMsgConn->SendPdu(&pdu2);
            }
            return;
        }
    }
    else
    {
        //no pc_client in this msg_server, check it from route_server
        CRouteServConn* pConn = get_route_serv_conn();
        CPduAttachData pduAttachData(ATTACH_TYPE_HANDLE_AND_PDU, pMsgConn->GetHandle(),
                                     pPdu->GetLength(), pPdu->GetBuffer());
        CImPduUserClientTypeRequest pdu3(to_id, pduAttachData.GetLength(), pduAttachData.GetBuffer());
        pdu3.SetReserved(pPdu->GetReserved());
        pConn->SendPdu(&pdu3);
    }
}
Esempio n. 7
0
void route_server_conn_timer_callback(void* callback_data, uint8_t msg, uint32_t handle, void* pParam)
{
	ConnMap_t::iterator it_old;
	CRouteServConn* pConn = NULL;
	uint64_t cur_time = get_tick_count();

	for (ConnMap_t::iterator it = g_route_server_conn_map.begin(); it != g_route_server_conn_map.end(); ) {
        it_old = it;
        it++;
        pConn = (CRouteServConn*)it_old->second;
        pConn->OnTimer(cur_time);
	}

	// reconnect RouteServer
	serv_check_reconnect<CRouteServConn>(g_route_server_list, g_route_server_count);
}
Esempio n. 8
0
void update_master_route_serv_conn()
{
	uint64_t oldest_connect_time = (uint64_t)-1;
	CRouteServConn* pOldestConn = NULL;

	CRouteServConn* pConn = NULL;

	for (uint32_t i = 0; i < g_route_server_count; i++) {
		pConn = (CRouteServConn*)g_route_server_list[i].serv_conn;
		if (pConn && pConn->IsOpen() && (pConn->GetConnectTime() < oldest_connect_time) ){
			pOldestConn = pConn;
			oldest_connect_time = pConn->GetConnectTime();
		}
	}

	g_master_rs_conn =  pOldestConn;

	if (g_master_rs_conn) {
		CImPduRoleSet pdu(1);
		g_master_rs_conn->SendPdu(&pdu);
	}
}
Esempio n. 9
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);
    }
}
Esempio n. 10
0
void CDBServConn::_HandleValidateResponse(CImPduValidateResponse* pPdu)
{
    string user_name(pPdu->GetUserName(), pPdu->GetUserNameLen());
	uint32_t result = pPdu->GetResult();
    CDbAttachData attach_data(pPdu->GetAttachData(), pPdu->GetAttachLen());
	log("HandleValidateResp, user_name=%s, result=%d\n", user_name.c_str(), result);

    CImUser* pImUser = CImUserManager::GetInstance()->GetImUserByName(user_name);
	CMsgConn* pMsgConn = NULL;
	if (!pImUser) {
		// can not find the client connection,
		// maybe the client is closed before the DB response arrived
		// do nothing
		log("ImUser for user_name=%s not exist\n", user_name.c_str());
		return;
	} else {
        pMsgConn = pImUser->GetUnValidateMsgConn(attach_data.GetHandle());
		if (!pMsgConn || pMsgConn->IsOpen()) {
			log("no such connection or is validated, user_name=%s\n", user_name.c_str());
			return;
		}
	}

	if (result != 0) {
		result = REFUSE_REASON_DB_VALIDATE_FAILED;
	}
    
	// validate OK, set client validate past, and send FriendListRequest to db storage server
	// else close the client connection
	if (result == 0) {
        user_info_t* user = pPdu->GetUserInfo();
        pImUser->SetUser(user);
        pImUser->SetValidated();
        
        uint32_t user_id = user->user_id;
        CImUserManager::GetInstance()->AddImUserById(user_id, pImUser);
        pImUser->KickOutSameClientType(pMsgConn->GetClientType(), pMsgConn);
        
        CRouteServConn* pRouteConn = get_route_serv_conn();
        if (pRouteConn) {
            CImPduServerKickUser kickPdu(user_id, pMsgConn->GetClientType(), KICK_REASON_DUPLICATE_USER);
            pRouteConn->SendPdu(&kickPdu);
        }
        
        string token = create_uuid();
        log("user_name: %s, uid: %d, token:%s\n", user_name.c_str(), user->user_id, token.c_str());
        pMsgConn->SetToken(token);
        pMsgConn->SetOpen();
        pMsgConn->SendUserActionLog(USER_ACTION_TYPE_LOGIN);
        pMsgConn->SendUserStatusUpdate(USER_STATUS_ONLINE);
        pImUser->ValidateMsgConn(token, pMsgConn);

        CImPduLoginResponse pduLR(result, pImUser->GetIMOnlineStatus(), user, (char*)token.c_str());
        pduLR.SetReserved(pPdu->GetReserved());
        pMsgConn->SendPdu(&pduLR);
	} else {
        CImPduLoginResponse pduLR(result);
        pduLR.SetReserved(pPdu->GetReserved());
        pMsgConn->SendPdu(&pduLR);
        //pMsgConn->Close();
	}
}
Esempio n. 11
0
void CDBServConn::_HandleValidateResponse(CImPdu* pPdu)
{
    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);
    CMsgConn* 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);
        
        CRouteServConn* 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);  //1是什么鬼

            pRouteConn->SendPdu(SID_OTHER, CID_OTHER_SERVER_KICK_USER, msg2);
        }
        
        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_sign_info(user_info.sign_info());
        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());

        pMsgConn->SendPdu(SID_LOGIN, CID_LOGIN_RES_USERLOGIN, msg3);
    }
    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);

        pMsgConn->SendPdu(SID_LOGIN, CID_LOGIN_RES_USERLOGIN, msg4);

        pMsgConn->Close();
    }
}
Esempio n. 12
0
void CDBServConn::_HandleValidateResponse(CImPdu* pPdu)
{
    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());
    struct timeval now;
    gettimeofday(&now, NULL);
    uint32_t rand_num = rand();
    string strKey = int2string(now.tv_usec % 10000) + int2string(now.tv_sec) + int2string(rand_num);
    strKey += strKey;
    uint32_t nKeyLen = strKey.length();
    if (nKeyLen < 32) {
        for (uint32_t i=nKeyLen; i<32; i++)
            strKey += '0';
    }
    else
    {
        strKey = strKey.substr(0, 32);
    }
    log("HandleValidateResp, user_name=%s, result=%d, key=%s", login_name.c_str(), result, strKey.c_str());
    
    CImUser* pImUser = CImUserManager::GetInstance()->GetImUserByLoginName(login_name);
    CMsgConn* 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;
        }
        log("_HandleValidateResponse, user=%s(%p) conn=%p", login_name.c_str(), pImUser, pMsgConn);
    }
    
    if (result != 0) {
        result = IM::BaseDefine::REFUSE_REASON_DB_VALIDATE_FAILED;
    }

    log("_HandleValidateResponse, login_user=%s key=%s %p ", login_name.c_str(), strKey.c_str(), pMsgConn);
    total_users++;
    switch(pMsgConn->GetClientType())
    {
        case IM::BaseDefine::CLIENT_TYPE_WINDOWS:
        case IM::BaseDefine::CLIENT_TYPE_MAC:
            pc_total_users++;
            break;
        case IM::BaseDefine::CLIENT_TYPE_ANDROID:
            android_total_users++;
            break;
        case IM::BaseDefine::CLIENT_TYPE_IOS:
            ios_total_users++;
            break;
        case IM::BaseDefine::CLIENT_TYPE_WEB:
            web_total_users++;
            break;
    }
    
    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)
        {
            log("_HandleValidateResponse, get user %u(%p) key=%s %p", user_id, pUser, strKey.c_str(), pMsgConn);
            pUser->AddUnValidateMsgConn(pMsgConn);
            pImUser->DelUnValidateMsgConn(pMsgConn);
            if (pImUser->IsMsgConnEmpty())
            {
                CImUserManager::GetInstance()->RemoveImUserByLoginName(login_name);
                delete pImUser;
            }
        }
        else
        {
            pUser = pImUser;
            log("_HandleValidateResponse, use login user %u(%p) key=%s %p", user_id, pUser, strKey.c_str(), pMsgConn);
        }
        
        pUser->SetUserId(user_id);
        pUser->SetNickName(user_info.user_nick_name());
        pUser->SetValidated();
        CImUserManager::GetInstance()->AddImUserById(user_id, pUser);
        
        log("user_name: %s, uid: %d(%p)", login_name.c_str(), user_id, pMsgConn);
        pMsgConn->SetKey(strKey);
        pMsgConn->SetUserId(user_id);
        pMsgConn->SetOpen();
        pMsgConn->SendUserStatusUpdate(IM::BaseDefine::USER_STATUS_ONLINE);
        
        CRouteServConn* 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);
        }
        
        pUser->ValidateMsgConn(pMsgConn->GetHandle(), pMsgConn);
        //pUser->KickOutSameClientType(pMsgConn->GetClientType(), IM::BaseDefine::KICK_REASON_DUPLICATE_USER, user_id);
        pUser->KickOutSameClientType(pMsgConn->GetClientType(), IM::BaseDefine::KICK_REASON_DUPLICATE_USER, 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());
        msg3.set_client_key(strKey);
        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_sign_info(user_info.sign_info());
        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());
        user_info_tmp->set_user_type(user_info.user_type());
        log("id:%u gender:%u nick:%s avatar:%s sign:%s depid:%u email:%s name:%s tel:%s uname:%s status:%u type:%u", user_info.user_id(), user_info.user_gender(), user_info.user_nick_name().c_str(), user_info.avatar_url().c_str(), user_info.sign_info().c_str(), user_info.department_id(), user_info.email().c_str(), user_info.user_real_name().c_str(), user_info.user_tel().c_str(), user_info.user_domain().c_str(), user_info.status(), user_info.user_type());
        CImPdu pdu2;
        pdu2.SetPBMsg(&msg3);
        pdu2.SetServiceId(SID_LOGIN);
        pdu2.SetCommandId(CID_LOGIN_RES_USERLOGIN);
        pdu2.SetSeqNum(pPdu->GetSeqNum());
        pMsgConn->SendPdu(&pdu2);
    }
    else
    {
        fail_users++;
        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();
    }
}