#include "netclient.h" #include "../model/datacenter.h" using namespace model; namespace network { NetClient::NetClient(model::DataCenter* dataCenter) :dataCenter(dataCenter) { initWebSocket(); } void NetClient::ping() { QNetworkRequest httpReq; httpReq.setUrl(QUrl(HTTP_URL + "/ping")); QNetworkReply* httpResp = httpClient.get(httpReq); connect(httpResp, &QNetworkReply::finished, this, [=]() { //到这里面,说明响应已经回了 if (httpResp->error() != QNetworkReply::NoError) { //请求失败 LOG() << "HTTP请求失败!!!" << httpResp->errorString(); httpResp->deleteLater(); return; } //获取到响应的body QByteArray body = httpResp->readAll(); LOG() << "响应的内容: " << body; httpResp->deleteLater(); }); } void NetClient::initWebSocket() { //准备好所需要的信号槽 connect(&websocketClient, &QWebSocket::connected, this, [=]() { LOG() << "webSocket 连接成功"; //连接成功之后,进行发送身份认证 sendAuth(); }); connect(&websocketClient, &QWebSocket::disconnected, this, [=]() { LOG() << "webSocket 连接断开"; }); connect(&websocketClient, &QWebSocket::textMessageReceived, this, [=](const QString& message) { LOG() << "webSocket 收到文本消息 " << message; }); connect(&websocketClient, &QWebSocket::binaryMessageReceived, this, [=](const QByteArray& byteArray) { LOG() << "webSocket 收到二进制的消息" << byteArray.length(); //TODO }); //和服务器真正建立连接 websocketClient.open(WEBSOCKET_URL); } void NetClient::sendAuth() { bite_im::ClientAuthenticationReq req; req.setRequestId(makeRequestId()); req.setSessionId(dataCenter->getLoginSessionId()); QByteArray body = req.serialize(&serializer); websocketClient.sendBinaryMessage(body); LOG() << "[WS身份认证] requestId= " << req.requestId() << ",loginSessionId= " << req.sessionId(); } QString NetClient::makeRequestId() { //基本的要求,确保每个请求的Id都是不重复的(唯一的) //通过UUID实现上述的效果 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) { //构造出HTTP请求body部分 bite_im::GetUserInfoReq req; req.setRequestId(makeRequestId()); req.setSessionId(loginSessionId); QByteArray body = req.serialize(&serializer); LOG() << "获取个人信息->发送请求: requestId=" << req.requestId() << ", loginSessionId=" << loginSessionId; //构造出HTTP请求 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(); ////针对body进行反序列化,解析成对象 //bite_im::GetUserInfoRsp respObj; //respObj.deserialize(&serializer, respBody); ////判定一下业务上是否出错 //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(); }); } void NetClient::getFriendList(const QString loginSessionId) { //通过protobuf构造body bite_im::GetFriendListReq req; req.setRequestId(makeRequestId()); req.setSessionId(loginSessionId); QByteArray body = req.serialize(&serializer); LOG() << "获取好友列表->发送请求 requestId=" << req.requestId() << ", loginSessionId= " << loginSessionId; //发送HTTP请求 QNetworkReply* httpResp = this->sendHttpRequest("/service/friend/get_friend_list", body); //处理响应 connect(httpResp, &QNetworkReply::finished, this, [=]() { //解析响应 bool ok = false; QString reason; auto friendListResp = this->handleHttpResponse(httpResp, &ok, &reason); if (!ok) { LOG() << "获取好友列表->失败 requestId= " << req.requestId() << ", reason= " << reason; } LOG() << "获取好友列表->成功"; //把结果保存在DataCenter中 dataCenter->resetFriendList(friendListResp); // 发送信号 emit dataCenter->getFriendListDone(); }); } } //end namespace network