TeamTalk 添加修改群组名功能

此为信令扩展部分 关键部分如下

1定义群组CMD

pb/IM.BaseDefine.proto

CID_GROUP_CHANGE_NAME_REQUEST = 0x040c,//群组名修改请求

CID_GROUP_CHANGE_NAME_RESPONSE = 0x040d,//响应

CID_GROUP_CHANGE_NAME_NOTIFY = 0x040e,//通知

2定义群组协议修改群名 req  rsp notify

pb/IM.Group.proto

message IMGroupChangeGroupNameReq{
	//cmd id:			0x040c
	required uint32 user_id = 1;
	required uint32 group_id = 2;
	required string group_name = 3;
	optional bytes attach_data = 20;
}

message IMGroupChangeGroupNameRsp{
	//cmd id:			0x040d
	required uint32 user_id = 1;
	required uint32 group_id = 2;
	required uint32 result_code = 3;
	optional bytes attach_data = 20;
	repeated uint32 cur_user_id_list = 4;	//notify  stick
}

message IMGroupChangeGroupNameNotifyRsp{
	//cmd id:			0x040d
	required uint32 user_id = 1;
	required uint32 group_id = 2;
	required string group_name = 3;
	repeated uint32 cur_user_id_list = 4;			//现有的成员id
	optional bytes attach_data = 20;
}

3生成协议

cd pb

./create.sh      

./sync.sh

4注册Db HandlerMap接口

dg/business/GroupAction.h


#include "ImPduBase.h"

namespace DB_PROXY {

    void createGroup(CImPdu* pPdu, uint32_t conn_uuid);
    
   ...



    void changeGroupName(CImPdu* pPdu, uint32_t conn_uuid);

};
    // group
    m_handler_map.insert(make_pair(uint32_t(CID_GROUP_NORMAL_LIST_REQUEST), 
...
....
    m_handler_map.insert(make_pair(uint32_t(CID_GROUP_CHANGE_NAME_REQUEST), DB_PROXY::changeGroupName));

GroupAction.cpp  添加实现

 /**
     *  modify group name 
     *
     *  @param pPdu      收到的packet包指针
     *  @param conn_uuid 该包过来的socket 描述符
     */
    void changeGroupName(CImPdu *pPdu, uint32_t conn_uuid)
    {
        IM::Group::IMGroupChangeGroupNameReq msg;
        IM::Group::IMGroupChangeGroupNameRsp msgResp;
        if (msg.ParseFromArray(pPdu->GetBodyData(), pPdu->GetBodyLength()))
        {

            uint32_t nUserId = msg.user_id();
            uint32_t nGroupId = msg.group_id();
            string strGroupName = msg.group_name();
            if (CGroupModel::getInstance()->isValidateGroupId(nGroupId))
            {
                CImPdu *pPduRes = new CImPdu;

                log("change group name  uid = %d group_id = %d name = %s", nUserId, nGroupId, strGroupName.c_str());

                bool bRet = CGroupModel::getInstance()->changeGroupName(nUserId,nGroupId, strGroupName);

                msgResp.set_user_id(nUserId);
                msgResp.set_group_id(nGroupId);
               msgResp.set_result_code(bRet ? 0 : 1);
                //query all users in group and notify
                list<uint32_t> lsCurUserId;
                CGroupModel::getInstance()->getGroupUser(nGroupId, lsCurUserId);
                for (auto it = lsCurUserId.begin(); it != lsCurUserId.end(); ++it)
                {
                    msgResp.add_cur_user_id_list(*it);
                }
                //response
                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_CHANGE_NAME_RESPONSE);
                CProxyConn::AddResponsePdu(conn_uuid, pPduRes);
            }
            else
            {
                log("invalid groupModifyType or groupId. userId=%u, groupId=%u", nUserId, nGroupId);
            }
        }
        else
        {
            log("parse pb failed");
        }
    }
}

5 添加数据库修改群名接口 同时更新 update字段 

GroupModel.cpp

bool CGroupModel::changeGroupName(uint32_t nUserId, uint32_t nGroupId, const string &strGroupName)
{
    bool bRet = false;
    if (hasModifyPermission(nUserId, nGroupId))
    {
        bRet = updateGroupName(nGroupId, strGroupName);
        //if modify group member success, need to inc the group version and clear the user count;
        if (bRet)
        {
            incGroupVersion(nGroupId);
        }
    }
    else
    {
        log("user:%u has no permission to modify group:%u", nUserId, nGroupId);
    }
    return bRet;
}


bool CGroupModel::updateGroupName(uint32_t nGroupId, const string &strGroupName)
{
    bool bRet = false;
    CDBManager *pDBManager = CDBManager::getInstance();
    CDBConn *pDBConn = pDBManager->GetDBConn("teamtalk_master");
    if (pDBConn)
    {
        uint32_t nNow = (uint32_t)time(NULL);
        // string strSql = "update IMGroup set name= " + strGroupName + " where id=" + int2string(nGroupId);
        // string strSql = "update IMGroup set `name`='" + strGroupName + "'  ,' updated'=" + int2string(nNow) + " where id=" + int2string(nGroupId);

        string strSql = "update IMGroup set `name`='" + strGroupName + "', `updated`=" + int2string(nNow) + " where id="+int2string(nGroupId);

        log("updateGroupName,%s ", strSql.c_str());
        bRet = pDBConn->ExecuteUpdate(strSql.c_str());
        pDBManager->RelDBConn(pDBConn);
    }
    else
    {
        log("no db connection for teamtalk_master");
    }
    return bRet;
}

6添加MSG_server   req HandleGroupNameResponse  HandleGroupNameNotify  接口

msg_server处理请求

MsgConn.cpp

void CMsgConn::HandlePdu(CImPdu* pPdu)
{
	// request authorization check
	if (pPdu->GetCommandId() != CID_LOGIN_REQ_USERLOGIN && !IsOpen() && IsKickOff()) {
        log("HandlePdu, wrong msg. ");
        throw CPduException(pPdu->GetServiceId(), pPdu->GetCommandId(), ERROR_CODE_WRONG_SERVICE_ID, "HandlePdu error, user not login. ");
		return;
    }
	switch (pPdu->GetCommandId()) {
        case CID_OTHER_HEARTBEAT:
      ...
   case CID_GROUP_CHANGE_NAME_REQUEST:
            s_group_chat->HandleClientGroupChangeNameRequest(pPdu, this);
            break;
        default:
            log("wrong msg, cmd id=%d, user id=%u. ", pPdu->GetCommandId(), GetUserId());
            break;
	}
}

groupchat.h 

    void HandleClientGroupChangeNameRequest(CImPdu* pPdu, CMsgConn* pFromConn);
    void HandleGroupChangeNameResponse(CImPdu* pPdu);
    void HandleGroupChangeNameBroadcast(CImPdu* pPdu);

groupchat.cpp

void CGroupChat::HandleClientGroupChangeNameRequest(CImPdu* pPdu, CMsgConn* pFromConn)
{
    IM::Group::IMGroupChangeGroupNameReq msg;
    CHECK_PB_PARSE_MSG(msg.ParseFromArray(pPdu->GetBodyData(), pPdu->GetBodyLength()));

	uint32_t req_user_id = pFromConn->GetUserId();
	uint32_t group_id = msg.group_id();
	string group_name = msg.group_name();
	log("HandleClientChangeNameReq,  req_id=%u, group_id=%u,",
			 req_user_id, group_id);

	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::IMGroupChangeGroupNameRsp msg2;
        msg2.set_user_id(req_user_id);
        msg2.set_result_code(1);
        msg2.set_group_id(group_id);
        CImPdu pdu;
        pdu.SetPBMsg(&msg2);
        pdu.SetServiceId(SID_GROUP);
        pdu.SetCommandId(CID_GROUP_CHANGE_NAME_RESPONSE);
		pdu.SetSeqNum(pPdu->GetSeqNum());
		pFromConn->SendPdu(&pdu);
	}
}

void CGroupChat::HandleGroupChangeNameResponse(CImPdu* pPdu)
{
    IM::Group::IMGroupChangeGroupNameRsp msg;
    CHECK_PB_PARSE_MSG(msg.ParseFromArray(pPdu->GetBodyData(), pPdu->GetBodyLength()));

	uint32_t user_id = msg.user_id();
	uint32_t result = msg.result_code();
	uint32_t group_id = msg.group_id();
	log("HandleGroupChangeNameResponse, req_id=%u, group_id=%u, result=%u",
			 user_id, group_id, result);

    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::IMGroupChangeGroupNameNotifyRsp msg2;
        
        msg2.set_user_id(user_id);
        msg2.set_group_id(group_id);
        // msg2.set_group_name();
        int cur_user_cnt = msg2.cur_user_id_list_size();
        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_NAME_NOTIFY);
		CRouteServConn* pRouteConn = get_route_serv_conn();
		if (pRouteConn) {
			pRouteConn->SendPdu(&pdu);
		}
        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);
        }
    }
}

void CGroupChat::HandleGroupChangeNameBroadcast(CImPdu* pPdu)
{
    IM::Group::IMGroupChangeMemberNotify msg;
    CHECK_PB_PARSE_MSG(msg.ParseFromArray(pPdu->GetBodyData(), pPdu->GetBodyLength()));

    uint32_t change_type = msg.change_type();
	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("HandleChangeMemberBroadcast, change_type=%u, group_id=%u, chg_user_cnt=%u, cur_user_cnt=%u. ", change_type, group_id, chg_user_cnt, cur_user_cnt);

    for (uint32_t i = 0; i < chg_user_cnt; i++)
    {
        uint32_t to_user_id = msg.chg_user_id_list(i);
        _SendPduToUser(pPdu, to_user_id);
    }
    for (uint32_t i = 0; i < cur_user_cnt; i++) {
        uint32_t to_user_id = msg.cur_user_id_list(i);
        _SendPduToUser(pPdu, to_user_id);
    }
}

DBServConn.cpp

void CDBServConn::HandlePdu(CImPdu* pPdu)
{
	switch (pPdu->GetCommandId()) {
        case CID_OTHER_HEARTBEAT:
            break;
       
      ...
      ...
     
       case CID_GROUP_CHANGE_NAME_RESPONSE:
            s_group_chat->HandleGroupChangeNameResponse(pPdu);
            break;
     
        
        default:
            log("db server, wrong cmd id=%d ", pPdu->GetCommandId());
	}
}

7编译 db msg模块 运行

更新 db

cd db_proxy_server

make clean 

cmake .

make 

cp db_proxy_server ../../../auto_setup/im_server/im-server-1/db_proxy_server

更新 msg_server

cd msg_server

make clean 

cmake .

make 

cp msg_server../../../auto_setup/im_server/im-server-1/msg_server

android 修改proto协议

copy文件

IMGroupManager 添加以下方法
 /**
     * 修改群组名
     *
     * @param name
     * @param groupId
     */
    public void reqChangeGroupName(final String name, int groupId) {
        if (TextUtils.isEmpty(name))
            return;
        final int loginId = imLoginManager.getLoginId();
        IMGroup.IMGroupChangeNameReq changeNameReq = IMGroup.IMGroupChangeNameReq.newBuilder()
                .setUserId(loginId)
                .setGroupId(groupId)
                .setGroupName(name)
                .build();

        int sid = IMBaseDefine.ServiceID.SID_GROUP_VALUE;
        int cid = IMBaseDefine.GroupCmdID.CID_GROUP_CHANGE_NAME_REQUEST_VALUE;
        imSocketManager.sendRequest(changeNameReq, sid, cid, new Packetlistener() {
            @Override
            public void onSuccess(Object response) {
                try {
                    IMGroup.IMGroupChangeNameRsp changeNameRsp = IMGroup.IMGroupChangeNameRsp.parseFrom((CodedInputStream) response);
                    IMGroupManager.instance().onReqChangeGroupName(changeNameRsp, name);
                } catch (IOException e) {
                    logger.e("reqChangeGroupName parse error!");
                    triggerEvent(new GroupEvent(GroupEvent.Event.CHANGE_GROUP_NAME_FAIL));
                }
            }

            @Override
            public void onFaild() {
                logger.e("reqChangeGroupName onFaild!");
                triggerEvent(new GroupEvent(GroupEvent.Event.CHANGE_GROUP_NAME_FAIL));
            }

            @Override
            public void onTimeout() {
                logger.e("reqChangeGroupName onTimeout!");
                triggerEvent(new GroupEvent(GroupEvent.Event.CHANGE_GROUP_NAME_TIMEOUT));
            }
        });

    }
    public void onReqChangeGroupName(IMGroup.IMGroupChangeNameRsp groupChangeNameRsp, String name) {
        int resultCode = groupChangeNameRsp.getResultCode();
        if (0 != resultCode) {
            triggerEvent(new GroupEvent(GroupEvent.Event.CHANGE_GROUP_NAME_FAIL));
            logger.e("reqChangeGroupMember onFaild! ,resultCode=%d", resultCode);
            return;
        }
        //TODO  notify 重复  delete
        int groupId = groupChangeNameRsp.getGroupId();
        String groupName = name;
        GroupEntity groupEntityRet = groupMap.get(groupId);
        groupEntityRet.setMainName(groupName);
        //更新db
        dbInterface.insertOrUpdateGroup(groupEntityRet);
        GroupEvent groupEvent;
        groupEvent = new GroupEvent(GroupEvent.Event.CHANGE_GROUP_NAME_SUCCESS);
        groupEvent.setGroupEntity(groupEntityRet);
        triggerEvent(groupEvent);
    }
    /**
     * 收到群成员发生变更消息
     * 服务端主动发出
     * DB
     */
    public void receiveGroupChangeMemberNotify(IMGroup.IMGroupChangeMemberNotify notify){
       int groupId =  notify.getGroupId();
       int changeType = ProtoBuf2JavaBean.getGroupChangeType(notify.getChangeType());
       List<Integer> changeList =  notify.getChgUserIdListList();

       List<Integer> curMemberList = notify.getCurUserIdListList();
       if(groupMap.containsKey(groupId)){
           GroupEntity entity = groupMap.get(groupId);
           entity.setlistGroupMemberIds(curMemberList);
           dbInterface.insertOrUpdateGroup(entity);
           groupMap.put(groupId,entity);

           GroupEvent groupEvent = new GroupEvent(GroupEvent.Event.CHANGE_GROUP_MEMBER_SUCCESS);
           groupEvent.setChangeList(changeList);
           groupEvent.setChangeType(changeType);
           groupEvent.setGroupEntity(entity);
           triggerEvent(groupEvent);
       }else{
           //todo 没有就暂时不管了,只要聊过天都会显示在回话里面
       }
    }

Guess you like

Origin blog.csdn.net/TyearLin/article/details/119737724