威海建设局官方网站长沙室内设计工作室
news/
2025/10/4 17:14:04/
文章来源:
威海建设局官方网站,长沙室内设计工作室,做网站图片太多怎么办,中信建设有限责任公司经济性质加载指定会话最近消息
前言
上一集我们就把三个标签页的加载列表的任务给完成啦#xff01;那么我们这一集就来完成加载指定绘画最近消息的任务。
需求分析
我们点击了某个会话之后#xff0c;我们就会去显示我们的会话的最近的N条消息。请看下图。 我们这里涉及到两个区…加载指定会话最近消息
前言
上一集我们就把三个标签页的加载列表的任务给完成啦那么我们这一集就来完成加载指定绘画最近消息的任务。
需求分析
我们点击了某个会话之后我们就会去显示我们的会话的最近的N条消息。请看下图。 我们这里涉及到两个区域一个是中间的区域一个是右边的消息展示区域。
当然这里我们只展示N条消息记录我们不多去展示不然影响我们的程序的效率和用户的体验感。这里和我们的返回历史消息记录查询是完全不同的东西
我们还是先来看一下我们的URL 再来看一眼我们的请求和响应的定义。 这就是我们这一集的任务要求
客户端
常规操作分两端这里是客户端的代码操作
loadRecentMessage
SessionItem::active
我们要考虑这个加载指定会话的最近消息要在哪里进行调用
我们应该在这个会话被点击的时候就加载这个函数那么我们就应该把这个函数放到我们SessionItem的active这个成员函数当中。
由于又要涉及到我们主界面的消息展示区那么这个函数必须放置在我们的主界面的代码当中。
那么我们就要获取到MainWidget的实例之后调用这个函数。
void SessionItem::active()
{LOG() 点击 SessionItem 触发的逻辑 chatSessionId chatSessionId;//加载会话历史消息会涉及到当前内存的数据操作又会涉及到网络通信还会涉及到界面的变更//使用到主窗口的方法进行调用MainWidget* mainWidget MainWidget::getInstance();mainWidget-loadRecentMessage(chatSessionId);}
loadRecentMessage的具体实现
我们需要传入需要加载的会话id因为我们不是加载整个最近消息所以我们要去传入会话id。
那么我们还是分为了两个部分一个是从内存进行加载一个是从网络进行加载。
我们判定的是这个会话的最近消息列表而不是整个最近的消息列表所以我们应该去访问key为chatSessionId的最近消息列表。我们判定整个会话的最近消息列表是没有什么用的
getRecentMessageList
QListMessage *DataCenter::getRecentMessageList(const QString chatSessionId)
{if(!recentMessage-contains(chatSessionId)){return nullptr;}return (*recentMessage)[chatSessionId];
}
我们先完成这个判定的函数这里我们要先去访问这个哈希表是否存在这个chatSessionId的列表如果没有就直接返回一个nullptr即可如果有就返回这个列表的指针即可。
void MainWidget::loadRecentMessage(const QString chatSessionId)
{//先判定本地是否存有数据DataCenter* dataCenter DataCenter::getInstance();//判定的是这个会话的最近消息列表不是整个最近消息列表if(dataCenter-getRecentMessageList(chatSessionId) ! nullptr){//本地数据加载updateRecentMessage(chatSessionId);}else{//网络数据加载connect(dataCenter, DataCenter::getRecentMessageListDone, this, MainWidget::updateRecentMessage, Qt::UniqueConnection);dataCenter-getRecentMessageListAsync(chatSessionId);}}
本地数据加载
updateRecentMessage
这个代码也是分为两个部分我们先讲这个本地数据加载的内容。
我们这里不要忘了这个内容是展示到我们的消息展示区的不是我们的好友列表上
我们先从DataCenter中获取这个列表之后清空我们整个消息展示区之后头插我们的消息内容。我们判定我们的消息是靠左还是靠右只需要去看这个消息的发送者的userId和我们DataCenter里面保存的Myself的userId即可。
之后我们要设置我们的会话标题再把我们当前选中的会话保存到我们的DataCenter当中。最后我们再来一个滚动条设置滑动到我们的消息的末尾即可。
void MainWidget::updateRecentMessage(const QString chatSessionId)
{//获取最近的消息列表DataCenter* dataCenter DataCenter::getInstance();auto* recentMessageList dataCenter-getRecentMessageList(chatSessionId);//这里不要把内容添加到会话了这里是要添加到消息展示区上//清空原有界面上的消息列表messageShowArea-clear();//遍历//要先看到最近消息那就是用头插for(int i recentMessageList-size() - 1; i 0; --i){const Message message recentMessageList-at(i);bool isLeft message.sender.userId ! dataCenter-getMyself()-userId;//用这个消息的发送者的用户id和数据中心的自身信息的用户id对比即可messageShowArea-addFrontMessage(isLeft, message);}//设置会话标题ChatSessionInfo* chatSessionInfo dataCenter-findChatSessionById(chatSessionId);if(chatSessionInfo ! nullptr){//把会话的名称显示到界面上sessionTitleLabel-setText(chatSessionInfo-chatSessionName);}//保存当前选中的会话dataCenter-setCurrentChatSessionId(chatSessionId);//自动把滚动条滚动到末尾就可以先看到最近的第一条消息messageShowArea-scrollToEnd();}
这里我们还要去是完成获取会话消息保存当前选中会话以及自动滑动滚动条到末尾的三个重要函数。
findChatSessionById
我们通过chatSessionId从DataCenter当中寻找会话列表中的指定会话的信息。
ChatSessionInfo *DataCenter::findChatSessionById(const QString chatSessionId)
{//判断会话列表是否为空if(chatSessionList nullptr){return nullptr;}for(auto info : *chatSessionList){if(info.chatSessionId chatSessionId){return info;}}//没找到return nullptr;
}
set/getCurrentChatSessionId
void DataCenter::setCurrentChatSessionId(const QString chatSessionId)
{this-currentChatSessionId chatSessionId;
}const QString DataCenter::getCurrentChatSessionId()
{return currentChatSessionId;
}scrollToEnd
void MessageShowArea::scrollToEnd()
{//获取垂直滚动条//获取到最大值//延时操作QTimer* timer new QTimer();connect(timer, QTimer::timeout, this, [](){int maxValue this-verticalScrollBar()-maximum();this-verticalScrollBar()-setValue(maxValue);timer-stop();timer-deleteLater();});timer-start(500);
}
使用延时操作等会话里的消息都加载到界面上我们再去获取到我们的具体滚动区域最大值之后滑动即可。
这样我们就可以通过本地数据进行加载我们指定会话的最近消息列表了
网络通信加载
getRecentMessageListAsync
我们不仅仅要传到NetClient的有loginSessionId我们还有指定的chatSessionId。
void DataCenter::getRecentMessageListAsync(const QString chatSessionId)
{netClient.getRecentMessageList(loginSessionId, chatSessionId);
}getRecentMessageList
我们还是老步骤啊构造请求body序列化之后发送请求到我们指定的URL之后处理我们的响应之后就是把我们的数据放置到我们的数据中心之后发送信号之后触发我们的信号槽从本地数据再获取数据即可
void NetClient::getRecentMessageList(const QString loginSessionId, const QString chatSessionId)
{//构造请求bodybite_im::GetRecentMsgReq req;req.setRequestId(makeRequestId());req.setChatSessionId(chatSessionId);req.setMsgCount(50);//固定获取50条req.setSessionId(loginSessionId);//序列化QByteArray body req.serialize(serializer);LOG() [获取最近消息] 发送请求 requestId req.requestId() , loginSessionId loginSessionId;//发送http请求QNetworkReply* resp this-sendHttpRequest(/service/message_storage/get_recent, body);//处理响应connect(resp, QNetworkReply::finished, this, [](){//解析响应bool ok false;QString reason;auto pbResp this-handleHttpResponsebite_im::GetRecentMsgRsp(resp, ok, reason);//判定响应是否okif(!ok){LOG() [获取最近消息] 失败! requestId req.requestId() , reason reason;return;}//设置到DataCenter中dataCenter-resetRecentMessageList(chatSessionId, pbResp);//发送信号告知界面进行更新emit dataCenter-getRecentMessageListDone(chatSessionId);});
}
resetRecentMessageList
这里我们不需要判定是否为空因为哈希的特性我们不存在就会直接创建我们记得清空一下这个指定会话的最近消息列表之后通过遍历我们把获得的数据设置到我们的recentMessage记住一定要用引用
void DataCenter::resetRecentMessageList(const QString chatSessionId, std::shared_ptrbite_im::GetRecentMsgRsp resp)
{//哈希的特性存在就使用不存在就创建新的清空QListMessage messageList (*recentMessage)[chatSessionId];messageList.clear();//遍历for(auto m : resp-msgList()){Message message;message.load(m);messageList.push_back(message);}
}
之后触发我们的信号就可以返回到我们的主界面那边了。 connect(dataCenter, DataCenter::getRecentMessageListDone, this, MainWidget::updateRecentMessage, Qt::UniqueConnection);
记得我们的第五个参数是为了防止一个信号触发我们多个这个槽函数。
到这里我们的客户端就完成了我们继续完成测试服务端
测试服务端
配置路由 httpServer.route(/service/message_storage/get_recent, [](const QHttpServerRequest req){return this-getRecent(req);});
基本操作我们直接到getRecent函数当中
getRecent
也是基本操作我们构造了一堆假数据放置到我们的界面上。
QHttpServerResponse HttpServer::getRecent(const QHttpServerRequest req)
{//解析请求bite_im::GetRecentMsgReq pbReq;pbReq.deserialize(serializer, req.body());LOG() [REQ 获取最近消息列表] requestId pbReq.requestId() , loginSessionId pbReq.sessionId();//构造响应bite_im::GetRecentMsgRsp pbResp;pbResp.setRequestId(pbReq.requestId());pbResp.setSuccess(true);pbResp.setErrmsg();QByteArray avatar loadFileToByteArray(:/resource/image/defaultAvatar.png);for(int i 0; i 20; i){bite_im::MessageInfo messageInfo makeTextMessageInfo(i, 2000, avatar);pbResp.msgList().push_back(messageInfo);}//序列化QByteArray body pbResp.serialize(serializer);//构造http响应对象QHttpServerResponse resp(body, QHttpServerResponse::StatusCode::Ok);resp.setHeader(Content-Type, application/x-protobuf);return resp;
}这里我们就完成了整个加载指定会话最近消息的内容了。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/927369.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!