前面准备了那么多,这里就直接是水到渠成了。
该讲的前面都讲的差不多了,剩下还没讲的都在代码里面。
不过由于文档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小时内删除侵权内容。