前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++搭建集群聊天室(十):登录与注册

C++搭建集群聊天室(十):登录与注册

作者头像
看、未来
发布2021-09-18 15:06:35
5980
发布2021-09-18 15:06:35
举报
文章被收录于专栏:CSDN搜“看,未来”

前面准备了那么多,这里就直接是水到渠成了。

该讲的前面都讲的差不多了,剩下还没讲的都在代码里面。

不过由于文档Telnet一直是发送不了数据的状态,就一直没法进一步的测试,等后面写了客户端再说。


chatservice.hpp

代码语言:javascript
复制
#ifndef CHATSERVICE_H_
#define CHATSERVICE_H_

#include<muduo/net/TcpConnection.h>
#include<unordered_map>
#include<functional>
#include<mutex>

#include "json.hpp"
#include "usermodel.hpp"

using json = nlohmann::json;
using namespace std;
using namespace muduo;
using namespace muduo::net;


//处理消息的事件回调方法类型
using MsgHandler = std::function<void(const TcpConnectionPtr &conn,json &js,Timestamp time)>;

//聊天服务器业务
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<int,MsgHandler> _msgHanderMap;

    //存储在线用户连接
    unordered_map<int,TcpConnectionPtr> _userConnMap;
    
    //数据操作类的对象
    UserModel _usermodel;

    //定义互斥锁
    mutex _connMutex;
};


#endif

chatservice.cpp

代码语言:javascript
复制
#include"chatservice.hpp"
#include"public.hpp"
#include<string>
#include<muduo/base/Logging.h>


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:"<<msgid<<"can not find handle!";
        };
    }
    else{
        return _msgHanderMap[msgid];
    }
}

void ChatService::login(const TcpConnectionPtr &conn,json &js,Timestamp time){
    int id = js["id"].get<int>();
    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<mutex> 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());
    }
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/08/17 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • chatservice.hpp
  • chatservice.cpp
相关产品与服务
腾讯云服务器利旧
云服务器(Cloud Virtual Machine,CVM)提供安全可靠的弹性计算服务。 您可以实时扩展或缩减计算资源,适应变化的业务需求,并只需按实际使用的资源计费。使用 CVM 可以极大降低您的软硬件采购成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档