diff --git a/mainwidget.cpp b/mainwidget.cpp index 102579f..153a809 100644 --- a/mainwidget.cpp +++ b/mainwidget.cpp @@ -284,8 +284,14 @@ void MainWidget::initSignalSlot() ///////////////////////////////////// // 获取个人的信息 ///////////////////////////////////// - - //dataCenter + //提供一个具体的方法,来获取到网络的数据 + connect(dataCenter, &DataCenter::getMyselfDone, this, [=]() { + //从DataCenter中拿到响应的结果myself,把里面的头像取出来,显示到界面上 + //由于响应的逻辑已经执行完毕,说明从网络拿到了信息,则直接同步获取即可 + auto myself = dataCenter->getMyselfsync(); + userAvatar->setIcon(myself->avatar); + }); + dataCenter->getMyselfAsync(); } void MainWidget::switchTabToSession() diff --git a/mainwidget.h b/mainwidget.h index be0821a..3fc8c1d 100644 --- a/mainwidget.h +++ b/mainwidget.h @@ -15,6 +15,7 @@ #include "addfrienddialog.h" #include "model/datacenter.h" + QT_BEGIN_NAMESPACE namespace Ui { class MainWidget; diff --git a/model/datacenter.cpp b/model/datacenter.cpp index 0831629..1423898 100644 --- a/model/datacenter.cpp +++ b/model/datacenter.cpp @@ -149,4 +149,18 @@ namespace model netClient.getMyself(loginSessionId); } + UserInfo* DataCenter::getMyselfsync() + { + return myself; + } + + void DataCenter::resetMyself(std::shared_ptr resp) + { + if (myself == nullptr) { + myself = new UserInfo(); + } + const bite_im::UserInfo& userInfo = resp->userInfo(); + myself->load(userInfo); + } + } //end namespace model diff --git a/model/datacenter.h b/model/datacenter.h index 6e0a774..a8feeee 100644 --- a/model/datacenter.h +++ b/model/datacenter.h @@ -97,6 +97,12 @@ namespace model //通过网络获取到用户的个人信息 void getMyselfAsync(); - signals: + UserInfo* getMyselfsync(); + // + void resetMyself(std::shared_ptr resp); + + signals: + //自定义信号 + void getMyselfDone(); }; } //end namespace model diff --git a/network/netclient.cpp b/network/netclient.cpp index 6f70e69..00287cf 100644 --- a/network/netclient.cpp +++ b/network/netclient.cpp @@ -74,48 +74,73 @@ namespace network { return "R" + QUuid::createUuid().toString().sliced(25, 12); } + //通过这个函数,把发送HTTP请求的操作封装一下 + QNetworkReply* NetClient::sendHttpRequest(const QString& apiPath, const QByteArray& body) + { + //构造出HTTP请求 + QNetworkRequest httpReq; + httpReq.setUrl(QUrl(HTTP_URL + apiPath)); + httpReq.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-protobuf"); + + //发起HTTP请求 + QNetworkReply* httpResp = httpClient.post(httpReq, body); + return httpResp; + } + //在这个函数内部,完成具体的网络通信即可 - void NetClient::getMyself(const QString& loginSessionId) + void NetClient::getMyself(const QString& loginSessionId) { //构造出HTTP请求body部分 bite_im::GetUserInfoReq req; req.setRequestId(makeRequestId()); req.setSessionId(loginSessionId); QByteArray body = req.serialize(&serializer); - LOG() << "获取个人信息: requestId=" << req.requestId() << ", loginSessionId=" << loginSessionId; + LOG() << "获取个人信息->发送请求: requestId=" << req.requestId() << ", loginSessionId=" << loginSessionId; //构造出HTTP请求 - QNetworkRequest httpReq; - httpReq.setUrl(QUrl(HTTP_URL + "/service/user/get_user_info")); - httpReq.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-protobuf"); - - //发起HTTP请求 - QNetworkReply* httpResp = httpClient.post(httpReq, body); + QNetworkReply* httpResp = sendHttpRequest("/service/user/get_user_info", body); //通过信号槽,获取到当前的响应 connect(httpResp, &QNetworkReply::finished, this, [=]() { - if (httpResp->error() != QNetworkReply::NoError) { - //说明HTTP请求出错了, - LOG() << "HTTP error: " << httpResp->errorString(); - httpResp->deleteLater(); - return; - } - //说明拿到了body - QByteArray respBody = httpResp->readAll(); + //if (httpResp->error() != QNetworkReply::NoError) { + // //说明HTTP请求出错了, + // LOG() << "HTTP error: " << httpResp->errorString(); + // httpResp->deleteLater(); + // return; + //} + ////说明拿到了body + //QByteArray respBody = httpResp->readAll(); - //针对body进行反序列化,解析成对象 - bite_im::GetUserInfoRsp respObj; - respObj.deserialize(&serializer, respBody); + ////针对body进行反序列化,解析成对象 + //bite_im::GetUserInfoRsp respObj; + //respObj.deserialize(&serializer, respBody); - //判定一下业务上是否出错 - if (!respObj.success()) { - LOG() << "requestId= " << respObj.requestId() << ", errmsg=" << respObj.errmsg(); - httpResp->deleteLater(); - return; - } + ////判定一下业务上是否出错 + //if (!respObj.success()) { + // LOG() << "requestId= " << respObj.requestId() << ", errmsg=" << respObj.errmsg(); + // httpResp->deleteLater(); + // return; + //} //继续处理后续的业务逻辑 + //获取http回复 + bool ok = false; + QString reason; + auto resp = handleHttpResponse(httpResp, &ok, &reason); + //判定响应是否正确 + if (!ok) { + LOG() << "获取个人信息->出错 requestId= " << req.requestId() << ", reason= " << reason; + return; + } + //把响应的数据保存到DataCenter + dataCenter->resetMyself(resp); + + //通知调用逻辑,响应已经处理完成了,仍然通过信号槽通知 + emit dataCenter->getMyselfDone(); + + //打印日志 + LOG() << "获取个人信息->响应处理完毕 requestId" << req.requestId(); }); } } //end namespace network \ No newline at end of file diff --git a/network/netclient.h b/network/netclient.h index d05bac1..57d1056 100644 --- a/network/netclient.h +++ b/network/netclient.h @@ -42,6 +42,42 @@ namespace network { //生成请求的Id static QString makeRequestId(); + //封装发送请求的逻辑 + QNetworkReply* sendHttpRequest(const QString& apiPath, const QByteArray& body); + + //封装处理响应的逻辑(判定HTTP正确性,反序列化,判断业务的正确性) + //由于不同的api返回的pb对象结构不同,为了让一个函数能够处理多种不同的类型,需要使用模板 + //后面两个是输出型参数,用于表示这次的操作是成功还是失败 + template + std::shared_ptr handleHttpResponse(QNetworkReply* httpResp, bool* ok, QString* reason) { + //判定HTTP层面上 + if (httpResp->error() != QNetworkReply::NoError) { + *ok = false; + *reason = httpResp->errorString(); + httpResp->deleteLater(); + return std::shared_ptr(); + } + + //说明并没有出错, 那就获取到响应的body + QByteArray respBody = httpResp->readAll(); + + //针对body反序列化 + std::shared_ptr respObj = std::make_shared(); + respObj->deserialize(&serializer, respBody); + + //判定业务的结构是否正确 + if (!respObj->success()) { + *ok = false; + *reason = respObj->errmsg(); + httpResp->deleteLater(); + return std::shared_ptr(); + } + + //释放httpResp对象 + httpResp->deleteLater(); + return respObj; + } + void getMyself(const QString& loginSessionId); private: model::DataCenter* dataCenter;