前面準備了那么多,這里就直接是水到渠成了。
該講的前面都講的差不多了,剩下還沒講的都在代碼里面。
不過由于文檔Telnet一直是發送不了數據的狀態,就一直沒法進一步的測試,等后面寫了客戶端再說。

chatservice.hpp
#ifndef CHATSERVICE_H_ #define CHATSERVICE_H_ #include #include #include #include #include "json.hpp" #include "usermodel.hpp" using json = nlohmann::json; using namespace std; using namespace muduo; using namespace muduo::net; //處理消息的事件回調方法類型 using MsgHandler = std::function; //聊天服務器業務 class ChatService{ public: //單例模式 static ChatService* instance(); void login(const TcpConnectionPtr &conn,json &js,Timestamp time); void reg(const TcpConnectionPtr &conn,json &js,Timestamp time); //獲取消息對應的處理器 MsgHandler getHandle(int msgid); private: ChatService(); //存儲消息id和對應的處理方法 unordered_map _msgHanderMap; //存儲在線用戶連接 unordered_map _userConnMap; //數據操作類的對象 UserModel _usermodel; //定義互斥鎖 mutex _connMutex; }; #endif
chatservice.cpp
#include"chatservice.hpp" #include"public.hpp" #include #include using namespace std; using namespace muduo; ChatService* ChatService::instance(){ static ChatService service; return &service; } //注冊消息以及對應的回調操作 ChatService::ChatService(){ _msgHanderMap.insert({LOGIN_TYPE,std::bind(&ChatService::login,this,_1,_2,_3)}); _msgHanderMap.insert({REG_TYPE,std::bind(&ChatService::reg,this,_1,_2,_3)}); } //獲取存儲消息id和對應的處理方法 MsgHandler ChatService::getHandle(int msgid){ //日志記錄 auto it = _msgHanderMap.find(msgid); if(it == _msgHanderMap.end()){ //返回一個lambda表達式,返回一個默認的空處理器,防止業務掛掉,后可做平滑升級處理 return [=](const TcpConnectionPtr &conn,json &js,Timestamp time){ LOG_ERROR<<"msgid:"<(); string pwd = js["password"]; User user = _usermodel.query(id); if (user.getID() == id && user.getpassword() == pwd) { if (user.getstate() == "online") { // 該用戶已經登錄,不允許重復登錄 json response; response["msgid"] = LOGIN_MSG_ACK; response["errno"] = 2; response["errmsg"] = "this account is using, input another!"; conn->send(response.dump()); } else { //添加作用域,限制鎖的粒度 { lock_guard lock(_connMutex); //記錄用戶連接 _userConnMap.insert({id,conn}); } // 登錄成功,更新用戶狀態信息 state offline=>online user.setstate("online"); _usermodel.updateState(user); json response; response["msgid"] = LOGIN_MSG_ACK; response["errno"] = 0; response["id"] = user.getID(); response["name"] = user.getname(); conn->send(response.dump()); } } else { // 該用戶不存在,用戶存在但是密碼錯誤,登錄失敗 json response; response["msgid"] = LOGIN_MSG_ACK; response["errno"] = 1; response["errmsg"] = "id or password is invalid!"; conn->send(response.dump()); } } void ChatService::reg(const TcpConnectionPtr &conn,json &js,Timestamp time){ string name = js["name"]; string pwd = js["password"]; User _user; _user.setname(name); _user.setpassword(pwd); bool state = _usermodel.insert(_user); if(state){ //注冊成功 json response; response["msgid"] = REG_MSG_ACK; response["errno"] = 0; response["id"] = _user.getID(); conn->send(response.dump()); } else{ //注冊失敗 json response; response["msgid"] = REG_MSG_ACK; response["errno"] = 1; conn->send(response.dump()); } }
C++
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。