好友认证
服务器响应
服务器接受客户端发送过来的好友认证请求
1 | void LogicSystem::AuthFriendApply(std::shared_ptr<CSession> session, const short& msg_id, const string& msg_data) { |
将请求注册到map里,在LogicSystem::RegisterCallBacks
中添加
1 | _fun_callbacks[ID_AUTH_FRIEND_REQ] = std::bind(&LogicSystem::AuthFriendApply, this, |
因为上面的逻辑调用了grpc发送通知,所以实现grpc发送认证通知的逻辑
1 | AuthFriendRsp ChatGrpcClient::NotifyAuthFriend(std::string server_ip, const AuthFriendReq& req) { |
这里注意,stub之所以能发送通知,是因为proto里定义了认证通知等服务,大家记得更新proto和我的一样,这事完整的proto
1 | syntax = "proto3"; |
为了方便生成grpcpb文件,我写了一个start.bat批处理文件
1 | @echo off |
执行这个批处理文件就能生成最新的pb文件了。
接下来实现grpc服务对认证的处理
1 | Status ChatServiceImpl::NotifyAuthFriend(ServerContext* context, const AuthFriendReq* request, |
所以A认证B为好友,A所在的服务器会给A回复一个ID_AUTH_FRIEND_RSP的消息,B所在的服务器会给B回复一个ID_NOTIFY_AUTH_FRIEND_REQ消息。
客户端响应
客户端需要响应服务器发过来的ID_AUTH_FRIEND_RSP和ID_NOTIFY_AUTH_FRIEND_REQ消息
客户端响应ID_AUTH_FRIEND_RSP,在initHandlers中添加
1 | _handlers.insert(ID_AUTH_FRIEND_RSP, [this](ReqId id, int len, QByteArray data) { |
在initHandlers中添加ID_NOTIFY_AUTH_FRIEND_REQ
1 | _handlers.insert(ID_NOTIFY_AUTH_FRIEND_REQ, [this](ReqId id, int len, QByteArray data) { |
客户端ChatDialog中添加对sig_add_auth_friend响应,实现添加好友到聊天列表中
1 | void ChatDialog::slot_add_auth_friend(std::shared_ptr<AuthInfo> auth_info) { |
客户端ChatDialog中添加对sig_auth_rsp响应, 实现添加好友到聊天列表中
1 | void ChatDialog::slot_auth_rsp(std::shared_ptr<AuthRsp> auth_rsp) |
因为认证对方为好友后,需要将申请页面的添加按钮变成已添加,所以ApplyFriendPage响应sig_auth_rsp信号
1 | void ApplyFriendPage::slot_auth_rsp(std::shared_ptr<AuthRsp> auth_rsp) { |
同意并认证对方为好友后,也需要将对方添加到联系人列表,ContactUserList响应sig_auth_rsp信号
1 | void ContactUserList::slot_auth_rsp(std::shared_ptr<AuthRsp> auth_rsp) |
登录加载好友
因为添加好友后,如果客户端重新登录,服务器LoginHandler需要加载好友列表,所以服务器要返回好友列表
1 | void LogicSystem::LoginHandler(shared_ptr<CSession> session, const short &msg_id, const string &msg_data) { |
客户端在initHandlers中加载聊天列表
1 | _handlers.insert(ID_CHAT_LOGIN_RSP, [this](ReqId id, int len, QByteArray data){ |
好友聊天
客户端发送聊天消息
客户端发送聊天消息,在输入框输入消息后,点击发送回执行下面的槽函数
1 | void ChatPage::on_send_btn_clicked() |
TcpMgr响应发送信号
1 | void TcpMgr::slot_send_data(ReqId reqId, QByteArray dataBytes) |
服务器响应
服务器响应客户端发送过来文本消息,在initHandlers中添加处理文本消息的逻辑
1 | void LogicSystem::DealChatTextMsg(std::shared_ptr<CSession> session, const short& msg_id, const string& msg_data) { |
服务器实现发送消息的rpc客户端
1 | TextChatMsgRsp ChatGrpcClient::NotifyTextChatMsg(std::string server_ip, |
服务器实现rpc服务端处理消息通知
1 | Status ChatServiceImpl::NotifyTextChatMsg(::grpc::ServerContext* context, |
客户端响应通知
客户端响应服务器返回的消息,包括两种:
- A给B发送文本消息,A所在的服务器会给A发送ID_TEXT_CHAT_MSG_RSP消息。
- B所在的服务器会通知B,告诉B有来自A的消息,通知消息为ID_NOTIFY_TEXT_CHAT_MSG_REQ
所以在tcpmgr的initHandlers中添加响应ID_TEXT_CHAT_MSG_RSP消息
1 | _handlers.insert(ID_TEXT_CHAT_MSG_RSP, [this](ReqId id, int len, QByteArray data) { |
在TcpMgr的initHandlers中添加ID_NOTIFY_TEXT_CHAT_MSG_REQ
1 | _handlers.insert(ID_NOTIFY_TEXT_CHAT_MSG_REQ, [this](ReqId id, int len, QByteArray data) { |
客户端ChatDialog添加对sig_text_chat_msg的响应
1 | void ChatDialog::slot_text_chat_msg(std::shared_ptr<TextChatMsg> msg) |
效果展示
源码连接
https://gitee.com/secondtonone1/llfcchat
视频连接
https://www.bilibili.com/video/BV1ib421J745/?vd_source=8be9e83424c2ed2c9b2a3ed1d01385e9