目錄
功能設計
模塊劃分
業務接口/功能示意圖
服務實現流程
網關HTTP接口
網關WebSocket接口
總體流程
服務代碼實現
客戶端長連接管理封裝(connectionManage.hpp)
proto文件的編寫
身份鑒權proto
事件通知proto
各項請求的URL的確定
服務端完成入口網關服務類(GatewayServer),進行其中的各項功能函數(請求處理函數)的實現
宏定義個功能請求的URL
GatewayServer類的成員變量和構造函數
WebSocketServer的三個回調函數實現
Speech::SpeechRecognize語音識別請求處理
File::SingleFileUp單文件上傳/發送單文件請求處理
File::MultiFileUp多文件上傳/發送多文件請求處理
File::SingleFileDonw單文件下載/獲取單文件數據請求處理
File::MultiFileDonw多文件下載/獲取多文件數據請求處理
User::UserNicknameRegistr用戶名注冊請求處理
User::UserNicknameLogin用戶名登陸請求處理
User::GetPhoneVerificationCode獲取手機驗證碼請求處理
User::UserPhoneRegister手機號注冊請求處理
User::UserPhoneLogin手機號登陸請求處理
User::GetOneUserInfo獲取用戶信息請求處理
User::SetUserAvatar設置用戶頭像請求處理
User::SetUserNickname設置用戶昵稱請求處理
User::SetUserDescription設置用戶簽名請求處理
User::SetUserPhone設置用戶手機號請求處理
Transmite::SendNewMessage發送新消息請求處理
Store::GetRecentNMessage獲取最近N條消息請求處理
Store::GetTimeRangeMessage獲取時間段消息請求處理
Store::GetMessageByKeyword消息關鍵字搜索請求處理
Friend::GetFriendList獲取好友列表請求處理
Friend::UserSearch用戶搜索請求處理
Friend::ApplyAddFriend申請添加好友請求處理
Friend::GetFriendApplyList獲取好友申請列表請求處理
Friend::FriendApplyEventHandle處理好友申請事件請求處理
Friend::RemoveFriend刪除好友請求處理
Friend::GetChatSessionList獲取聊天會話列表請求處理
Friend::CreateGroupChatSession創建群聊會話請求處理
Friend::GetChatSessionMember獲取會話成員請求處理
完成入口網關服務類的構造者(GatewayServerBuilder)
實例化服務對象,啟動服務
工程系統構建配置文件(CMakeLists.txt)
本章節,主要對項目中入口網關子服務模塊進行分析、開發與測試。
功能設計
入口網關子服務在設計中,最重要的兩個功能:
1、接收客戶端的所有請求,并解析,然后進行請求的子服務分發,得到響應后,再響應給客戶端。(其中這些請求再細化為具體的各項請求,一共28個)。
2、對客戶端進行事件通知:好友申請、申請處理、刪除好友、聊天會話的創建、新消息。
基于上述兩個功能,入口網關子服務包含兩種通信:
1、HTTP通信:進行接收請求,業務處理。
2、WebSocket通信:進行事件通知。
模塊劃分
參數/配置文件解析模塊 | 基于gflags框架直接使用,進行參數/配置文件的解析。 |
日志模塊 | 基于spdlog封裝的logger 直接進行日志輸出。 |
服務發現與調用模塊 | 基于etcd框架封裝的服務發現與brpc框架封裝的服務調用模塊。 因為要分發處理所有請求,需要發現所有的子服務模塊。 |
redis客戶端模塊 | 基于redis++封裝的客戶端進行內存數據庫的操作。 根據用戶管理子服務添加的登錄會話信息,進行用戶的身份鑒權和識別。 |
HTTP通信服務器模塊 | 基于httplib搭建HTTP服務器,接收HTTP請求,進行業務處理。 |
WebSocket服務器模塊 | 基于WebSocketpp,搭建WebSocket服務器,進行事件通知。 |
客戶端長連接Connection管理模塊 | 通過用戶ID 和 長連接句柄 建立映射關系,對長連接進行封裝,便于后續管理。 |
業務接口/功能示意圖
服務實現流程
網關HTTP接口
HTTP通信,分為首行、頭部和正文三部分。
首行中的URL明確了業務請求目標(目的地)。
頭部進行正文或連接描述。
正文中包含請求或響應的內容。
因此,之后實現的時候,首先就要確定各項URL。
其次,在HTTP請求正文中,將采用protobuf協議作為正文的序列化方式。不同的請求正文與后臺的請求基本上吻合,因此,請求正文結構 將與 后臺服務之間復用同一套接口。
網關WebSocket接口
WebSocket通信接口中,包含兩個方面:
1、長連接的身份識別。
當用戶登陸成功之后,向服務器發送WebSocket長連接請求,建立長連接。
長連接建立成功之后,向服務器發送身份鑒權請求,請求內容為protobuf結構數據,包含內容:請求ID、登錄會話ID。
該請求不需要服務端進行回復,鑒權成功則長連接保持,否則斷開長連接即可。
2、事件通知的內容。
因為事件通知在長連接中進行,因此,只需要定義出事件通知的消息結構即可。
總體流程
0、完成客戶端長連接管理的封裝。 |
1、編寫服務所需的proto文件,利用protoc工具生成RPC服務器所需的.pb.h 和 .pb.cc 項目文件。 |
2、完成各項功能函數(請求)的URL的編寫。 |
3、服務端完成入口網關服務類,進行其中的各項功能函數(請求處理函數)的實現。 |
4、實例化服務器對象,啟動服務。 |
服務代碼實現
客戶端長連接管理封裝(connectionManage.hpp)
在該封裝中,提供了4個API:
1、新增長連接管理。
2、移除長連接。
3、獲取長連接。
4、通過長連接獲取對應用戶(客戶端)信息。
#pragma once
#include <websocketpp/config/asio_no_tls.hpp>
#include <websocketpp/server.hpp>
#include <iostream>
#include "logger.hpp"namespace yangz
{typedef websocketpp::server<websocketpp::config::asio> websocket_server; // 簡單重定義websocket_server類型// 此時, 長連接的類型: websocket_server::connection_ptrclass Connection{public:// 長連接客戶端 -> user_id, login_session_idstruct Client{Client(const std::string &uid, const std::string &lssid) : user_id(uid), login_session_id(lssid) {}std::string user_id;std::string login_session_id;};using ptr = std::shared_ptr<Connection>;Connection() {}~Connection() {}public:// 新增長連接管理void append(const websocket_server::connection_ptr &connection, const std::string &user_id, const std::string &login_session_id){// connection_ptr是weak_ptr, 需要get獲取shared_ptrstd::unique_lock<std::mutex> lock(_mutex);_userid_connections.insert({user_id, connection});_connection_clients.insert({connection, Client(user_id, login_session_id)});LOG_DEBUG("新增長連接用戶信息, connection_ptr: {}, user_id: {}, login_session_id: {}", (size_t)connection.get(), user_id, login_session_id);}// 移除長連接void remove(const websocket_server::connection_ptr &connection){std::unique_lock<std::mutex> lock(_mutex);auto it = _connection_clients.find(connection);if (it == _connection_clients.end()){LOG_ERROR("刪除長連接時, 未找到該長連接, connection_ptr: {}", (size_t)connection.get());return;}_userid_connections.erase(it->second.user_id);_connection_clients.erase(it);LOG_DEBUG("移除長連接成功");}// 獲取該長連接websocket_server::connection_ptr get_connection(const std::string &user_id){std::unique_lock<std::mutex> lock(_mutex);auto it = _userid_connections.find(user_id);if (it == _userid_connections.end()){LOG_ERROR("獲取長連接時, 沒有找到該長連接, user_id: {}", user_id);return websocket_server::connection_ptr();}return it->second;}// 判斷該用戶是否已經建立了長連接, 同時獲取user_id 和 login_session_idbool client_is_connect(const websocket_server::connection_ptr &connection, std::string &user_id, std::string &login_session_id){std::unique_lock<std::mutex> lock(_mutex);auto it = _connection_clients.find(connection);if (it == _connection_clients.end()){LOG_ERROR("獲取用戶信息時, 該用戶并沒有建立長連接");return false;}user_id = it->second.user_id;login_session_id = it->second.login_session_id;return true;}private:std::mutex _mutex;std::unordered_map<std::string, websocket_server::connection_ptr> _userid_connections; // <user_id, 長連接>std::unordered_map<websocket_server::connection_ptr, Client> _connection_clients; // <長連接, [user_id, login_session_id]>};
}
proto文件的編寫
身份鑒權proto
入口網關子服務首先根據用戶請求中攜帶信息,通過長連接獲取到客戶端信息,然后根據redis數據庫中的信息進行審核。
因此,只需要一個簡單的protobuf結構的信息:user_id, login_session_id即可:
syntax = "proto3";
package yangz;
option cc_generic_services = true;// 用戶身份鑒權請求
message ClientIdentityAuthenticationReq
{string req_id = 1;string login_session_id = 2; // 登錄會話ID, 網關根據該字段識別長連接客戶端的身份
};
事件通知proto
在該proto文件中,要定義出來需要被通知的事件的protobuf結構數據:申請添加好友、處理申請結構、刪除好友、創建群聊、發送新消息。
syntax = "proto3";
package yangz;
import "base.proto";option cc_generic_services = true;enum MessageNotifyType
{APPLY_ADD_FRIEND_NOTIFY = 0; // 申請添加好友FRIEND_APPLY_EVENT_HANDLE_NOTIFY = 1; // 處理好友申請REMOVE_FRIEND_NOTIFY = 2; // 刪除好友CREATE_GROUP_CHAT_SESSION_NOTIFY = 3; // 創建群聊NEW_MESSAGE_NOTIFY = 4; // 新消息
}// 申請添加好友
message ApplyAddFriendNotify
{UserInfo user_info = 1; // 申請人信息
};// 好友申請請求處理
message FriendApplyEventHandleNotify
{bool agree = 1;UserInfo user_info = 2; // 處理人信息
};// 刪除好友
message RemoveFriendNotify
{string user_id = 1; // 主動刪除者的用戶ID
};// 創建群聊
message CreateGroupChatSessionNotify
{ChatSessionInfo chat_session_info = 1; // 聊天會話信息
};// 新聊天消息
message NewMessageNotify
{MessageInfo message_info = 1; // 消息元信息
};message NotifyMessage
{optional string notify_event_id = 1; // 通知事件IDMessageNotifyType notify_type = 2;oneof notify_remarks // 事件備注信息{ApplyAddFriendNotify apply_add_friend = 3;FriendApplyEventHandleNotify friend_apply_event_handle = 4;RemoveFriendNotify remove_friend = 5;CreateGroupChatSessionNotify create_group_chat_session = 6;NewMessageNotify new_message = 7;}
};
各項請求的URL的確定
對于客戶端的請求,該項目中一共提供28個請求功能,分別對應到各個子服務中,因此,需要提供28個URL,來對應子服務下的對應功能。
并且客戶端的請求采用HTTP模式進行通信,通信時采用Post作為請求方法。
SERVICE HHTP PATH:// 語音識別子服務
/service/speech_recognition/speech_recognize 語音識別// 文件管理子服務
/service/file_manage/up_single_file 發送/上傳單個文件
/service/file_manage/up_multi_file 發送/上傳多個文件
/service/file_manage/donw_single_file 獲取/下載單個文件
/service/file_manage/donw_single_file 獲取/下載多個文件// 用戶管理子服務
/service/user_manage/user_nickname_registr 用戶名注冊
/service/user_manage/user_nickname_login 用戶名登陸
/service/user_manage/get_phone_verification_code 獲取手機驗證碼
/service/user_manage/user_phone_registr 手機號注冊
/service/user_manage/user_phone_login 手機號登陸
/service/user_manage/get_one_user_info 獲取單個用戶信息
/service/user_manage/set_user_avatar 修改頭像
/service/user_manage/set_user_nickname 修改昵稱
/service/user_manage/set_user_description 修改簽名
/service/user_manage/set_user_phone 修改手機號// 消息轉發子服務
/service/message_transmite/send_new_message 發送新消息// 消息存儲子服務
/service/message_store/get_recent_n_message 獲取最近N條消息
/service/message_store/get_time_range_message 獲取指定時間段消息
/service/message_store/get_message_by_keyword 消息關鍵字搜索// 好友管理子服務
/service/friend_manage/get_friend_list 獲取好友列表
/service/friend_manage/user_search 用戶搜索
/service/friend_manage/apply_add_friend 申請添加好友
/service/friend_manage/get_friend_apply_list 獲取好友申請列表
/service/friend_manage/friend_apply_event_handle 處理好友申請
/service/friend_manage/remove_friend 刪除好友
/service/friend_manage/get_chat_session_list 獲取聊天會話列表
/service/friend_manage/create_group_chat_session 創建群聊會話
/service/friend_manage/get_chat_session_member 獲取聊天會話成員
服務端完成入口網關服務類(GatewayServer),進行其中的各項功能函數(請求處理函數)的實現
宏定義個功能請求的URL
// 各功能請求的URL
// speech_recognition_service
#define SPEECH_RECOGNITION "/service/speech_recognition/speech_recognize"// file_manage_service
#define UP_SINGLE_FILE "/service/file_manage/up_single_file"
#define UP_MULTI_FILE "/service/file_manage/up_multi_file"
#define DONW_SINGLE_FILE "/service/file_manage/donw_single_file"
#define DONW_MULTI_FILE "/service/file_manage/donw_multi_file"// user_manage_service
#define USER_NICKNAME_REGISTR "/service/user_manage/user_nickname_registr"
#define USER_NICKNAME_LOGIN "/service/user_manage/user_nickname_login"
#define GET_PHONE_VERIFICATION_CODE "/service/user_manage/get_phone_verification_code"
#define USER_PHONE_REGISTR "/service/user_manage/user_phone_registr"
#define USER_PHONE_LOGIN "/service/user_manage/user_phone_login"
#define GET_ONE_USER_INFO "/service/user_manage/get_one_user_info"
#define SET_USER_AVATAR "/service/user_manage/set_user_avatar"
#define SET_USER_NICKNAME "/service/user_manage/set_user_nickname"
#define SET_USER_DESCRIPTION "/service/user_manage/set_user_description"
#define SET_USER_PHONE "/service/user_manage/set_user_phone"// message_transmite_service
#define SEND_NEW_MESSAGE "/service/message_transmite/send_new_message"// message_store_service
#define GET_RECENT_N_MESSAGE "/service/message_store/get_recent_n_message"
#define GET_TIME_RANGE_MESSAGE "/service/message_store/get_time_range_message"
#define GET_MESSAGE_BY_KEYWORD "/service/message_store/get_message_by_keyword"// friend_manage_service
#define GET_FRIEND_LIST "/service/friend_manage/get_friend_list"
#define USER_SEARCH "/service/friend_manage/user_search"
#define APPLY_ADD_FRIEND "/service/friend_manage/apply_add_friend"
#define GET_FRIEND_APPLY_LIST "/service/friend_manage/get_friend_apply_list"
#define FRIEND_APPLY_EVENT_HANDLE "/service/friend_manage/friend_apply_event_handle"
#define REMOVE_FRIEND "/service/friend_manage/remove_friend"
#define GET_CHAT_SESSION_LIST "/service/friend_manage/get_chat_session_list"
#define CREATE_GROUP_CHAT_SESSION "/service/friend_manage/create_group_chat_session"
#define GET_CHAT_SESSION_MEMBER "/service/friend_manage/get_chat_session_member"
GatewayServer類的成員變量和構造函數
先定義各成員變量,然后進行列表初始化。
隨后在構造函數中,對websocket服務器進行初始化:設置建立長連接/關閉長連接/新消息到來的回調處理函數。
再對http服務器進行初始化:設置客戶端的Post請求處理方法,一共28個,之后再具體實現28個請求處理方法函數。
class GatewayServer{public:using ptr = std::shared_ptr<GatewayServer>;GatewayServer(const std::shared_ptr<sw::redis::Redis> &redis_client,const std::string &speech_recognition_service_name,const std::string &file_manage_service_name,const std::string &user_manage_service_name,const std::string &message_transmite_service_name,const std::string &message_store_service_name,const std::string &friend_manage_service_name,const ServiceDiscovery::ptr &sd_client,const ServiceChannelManager::ptr &channel_manager,int websocket_port,int http_port): _redis_login_session_client(std::make_shared<LoginSessionManage>(redis_client)),_redis_login_status_client(std::make_shared<LoginStatusManage>(redis_client)),_speech_recognition_service_name(speech_recognition_service_name),_file_manage_service_name(file_manage_service_name),_user_manage_service_name(user_manage_service_name),_message_transmite_service_name(message_transmite_service_name),_message_store_service_name(message_store_service_name),_friend_manage_service_name(friend_manage_service_name),_sd_client(sd_client),_channel_manager(channel_manager),_connections(std::make_shared<Connection>()){// init websocket server_websocket_server.set_access_channels(websocketpp::log::alevel::none); // 關閉日志輸出_websocket_server.init_asio(); // 初始化websocket的異步IO_websocket_server.set_open_handler(std::bind(&GatewayServer::open_callback, this, std::placeholders::_1)); // 設置websocket握手成功后的回調函數_websocket_server.set_close_handler(std::bind(&GatewayServer::close_callback, this, std::placeholders::_1)); // 設置websocket連接關閉的回調函數_websocket_server.set_message_handler(std::bind(&GatewayServer::newmessage_callback, this, std::placeholders::_1, std::placeholders::_2)); // 設置websocket新消息的回到處理函數_websocket_server.set_reuse_addr(true); // 啟動地址重用_websocket_server.listen(websocket_port); // 開始監聽_websocket_server.start_accept(); // 開始接收連接請求// init http server// 即設置各種客戶端Post請求的回調處理函數, 即28各功能請求處理函數// Port(URL, (httplib::Server::Handler)call_back)// speech_recognition_service_http_server.Post(SPEECH_RECOGNITION, (httplib::Server::Handler)std::bind(&GatewayServer::SpeechRecognize, this, std::placeholders::_1, std::placeholders::_2));// file_manage_service_http_server.Post(UP_SINGLE_FILE, (httplib::Server::Handler)std::bind(&GatewayServer::SingleFileUp, this, std::placeholders::_1, std::placeholders::_2));_http_server.Post(UP_MULTI_FILE, (httplib::Server::Handler)std::bind(&GatewayServer::MultiFileUp, this, std::placeholders::_1, std::placeholders::_2));_http_server.Post(DONW_SINGLE_FILE, (httplib::Server::Handler)std::bind(&GatewayServer::SingleFileDown, this, std::placeholders::_1, std::placeholders::_2));_http_server.Post(DONW_MULTI_FILE, (httplib::Server::Handler)std::bind(&GatewayServer::MultiFileDown, this, std::placeholders::_1, std::placeholders::_2));// user_manage_service_http_server.Post(USER_NICKNAME_REGISTR, (httplib::Server::Handler)std::bind(&GatewayServer::UserNicknameRegistr, this, std::placeholders::_1, std::placeholders::_2));_http_server.Post(USER_NICKNAME_LOGIN, (httplib::Server::Handler)std::bind(&GatewayServer::UserNicknameLogin, this, std::placeholders::_1, std::placeholders::_2));_http_server.Post(GET_PHONE_VERIFICATION_CODE, (httplib::Server::Handler)std::bind(&GatewayServer::GetPhoneVerificationCode, this, std::placeholders::_1, std::placeholders::_2));_http_server.Post(USER_PHONE_REGISTR, (httplib::Server::Handler)std::bind(&GatewayServer::UserPhoneRegister, this, std::placeholders::_1, std::placeholders::_2));_http_server.Post(USER_PHONE_LOGIN, (httplib::Server::Handler)std::bind(&GatewayServer::UserPhoneLogin, this, std::placeholders::_1, std::placeholders::_2));_http_server.Post(GET_ONE_USER_INFO, (httplib::Server::Handler)std::bind(&GatewayServer::GetOneUserInfo, this, std::placeholders::_1, std::placeholders::_2));_http_server.Post(SET_USER_AVATAR, (httplib::Server::Handler)std::bind(&GatewayServer::SetUserAvatar, this, std::placeholders::_1, std::placeholders::_2));_http_server.Post(SET_USER_NICKNAME, (httplib::Server::Handler)std::bind(&GatewayServer::SetUserNickname, this, std::placeholders::_1, std::placeholders::_2));_http_server.Post(SET_USER_DESCRIPTION, (httplib::Server::Handler)std::bind(&GatewayServer::SetUserDescription, this, std::placeholders::_1, std::placeholders::_2));_http_server.Post(SET_USER_PHONE, (httplib::Server::Handler)std::bind(&GatewayServer::SetUserPhone, this, std::placeholders::_1, std::placeholders::_2));// message_transmite_service_http_server.Post(SEND_NEW_MESSAGE, (httplib::Server::Handler)std::bind(&GatewayServer::SendNewMessage, this, std::placeholders::_1, std::placeholders::_2));// message_store_service_http_server.Post(GET_RECENT_N_MESSAGE, (httplib::Server::Handler)std::bind(&GatewayServer::GetRecentNMessage, this, std::placeholders::_1, std::placeholders::_2));_http_server.Post(GET_TIME_RANGE_MESSAGE, (httplib::Server::Handler)std::bind(&GatewayServer::GetTimeRangeMessage, this, std::placeholders::_1, std::placeholders::_2));_http_server.Post(GET_MESSAGE_BY_KEYWORD, (httplib::Server::Handler)std::bind(&GatewayServer::GetMessageByKeyword, this, std::placeholders::_1, std::placeholders::_2));// friend_manage_service_http_server.Post(GET_FRIEND_LIST, (httplib::Server::Handler)std::bind(&GatewayServer::GetFriendList, this, std::placeholders::_1, std::placeholders::_2));_http_server.Post(USER_SEARCH, (httplib::Server::Handler)std::bind(&GatewayServer::UserSearch, this, std::placeholders::_1, std::placeholders::_2));_http_server.Post(APPLY_ADD_FRIEND, (httplib::Server::Handler)std::bind(&GatewayServer::ApplyAddFriend, this, std::placeholders::_1, std::placeholders::_2));_http_server.Post(GET_FRIEND_APPLY_LIST, (httplib::Server::Handler)std::bind(&GatewayServer::GetFriendApplyList, this, std::placeholders::_1, std::placeholders::_2));_http_server.Post(FRIEND_APPLY_EVENT_HANDLE, (httplib::Server::Handler)std::bind(&GatewayServer::FriendApplyEventHandle, this, std::placeholders::_1, std::placeholders::_2));_http_server.Post(REMOVE_FRIEND, (httplib::Server::Handler)std::bind(&GatewayServer::RemoveFriend, this, std::placeholders::_1, std::placeholders::_2));_http_server.Post(GET_CHAT_SESSION_LIST, (httplib::Server::Handler)std::bind(&GatewayServer::GetChatSessionList, this, std::placeholders::_1, std::placeholders::_2));_http_server.Post(CREATE_GROUP_CHAT_SESSION, (httplib::Server::Handler)std::bind(&GatewayServer::CreateGroupChatSession, this, std::placeholders::_1, std::placeholders::_2));_http_server.Post(GET_CHAT_SESSION_MEMBER, (httplib::Server::Handler)std::bind(&GatewayServer::GetChatSessionMember, this, std::placeholders::_1, std::placeholders::_2));// http 新啟線程, 放置阻塞等待消息, 并分離_http_thread = std::thread([this, http_port](){ _http_server.listen("0.0.0.0", http_port); });_http_thread.detach();}// 服務器啟動void start(){_websocket_server.run();}private:// redisLoginSessionManage::ptr _redis_login_session_client; // 登錄會話操作句柄LoginStatusManage::ptr _redis_login_status_client; // 登陸狀態操作句柄// service namestd::string _speech_recognition_service_name;std::string _file_manage_service_name;std::string _user_manage_service_name;std::string _message_transmite_service_name;std::string _message_store_service_name;std::string _friend_manage_service_name;// service discoverServiceDiscovery::ptr _sd_client; // etcd.hpp中服務發現的操作句柄// channel managerServiceChannelManager::ptr _channel_manager; // 通信信道, 用于和子服務建立連接// connectionConnection::ptr _connections;// wevsocket & httpwebsocket_server _websocket_server;httplib::Server _http_server;std::thread _http_thread; // http新線程, 異步執行, 放置阻塞等候};
WebSocketServer的三個回調函數實現
握手成功回調函數:
簡單打印日志提示。
// websocket握手成功后的回調函數void open_callback(websocketpp::connection_hdl hdl){LOG_DEBUG("websocket長連接建立成功, connection: {}", (size_t)_websocket_server.get_con_from_hdl(hdl).get());}
連接關閉回調函數:
1、清理對應的connection緩存。
2、日志打印提示。
// websocket連接關閉的回調函數void close_callback(websocketpp::connection_hdl hdl){// 1. 獲取到connectionauto connection = _websocket_server.get_con_from_hdl(hdl);// 2. 通過connection獲取到客戶端信息std::string user_id, login_session_id;bool res = _connections->client_is_connect(connection, user_id, login_session_id);if (res == false){LOG_WARN("長連接斷開時, 未找到客戶端信息");return;}// 3. 移除相關管理信息_redis_login_session_client->remove(login_session_id);_redis_login_status_client->remove(user_id);_connections->remove(connection);LOG_DEBUG("長連接斷開, 清理緩存完成");}
新消息到來回調函數:
1、獲取其中的connection。
2、將消息正文反序列化。
3、提取login_session_id。
4、根據login_session_id在redis中進行身份查找。
5、添加長連接管理。
6、長連接進行保活。
// 設置websocket新消息的回到處理函數void newmessage_callback(websocketpp::connection_hdl hdl, websocket_server::message_ptr message){// 1. 獲取connectionauto connection = _websocket_server.get_con_from_hdl(hdl);// 2. 將消息中的ClientIdentityAuthenticationReq進行反序列化獲取ClientIdentityAuthenticationReq req