C++项目——集群聊天服务器项目(十)点对点聊天业务

本文详细介绍了如何在C++集群聊天服务器中实现点对点聊天功能,包括消息格式、在线离线判断、数据库操作(存储和查询离线消息)以及用户登录时的离线消息推送。通过实例展示了业务逻辑和代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本节来实现C++集群聊天服务器项目中的点对点聊天业务,一起来试试吧

一、点对点聊天业务

聊天服务器中一个重要的功能就是实现点对点聊天,客户端发送的信息包含聊天业务msgid、自身

的id和姓名、聊天对象的id号以及聊天信息,例如:

{"msgid":5,"id":13,"name":"zhang san","to":15,"msg":"Hello,Boy!"}

id号为13的张三用户要与id号为15的用户进行 点对点聊天业务,发送消息为Hello,Boy!

如果要聊天,那便是双方的

{"msgid":5,"id":15,"name":"lisi","to":13,"msg":"Hello,Hello."}

id号为15的李四用户与id号为13的用户聊天,发送消息为Hello,Hello.

二、点对点业务步骤

(1)从json传来的数据中,获取聊天对象的id号

    int to_id = js["to"].get<int>();

(2)点对点聊天,必须双方在线,如果不在线,则发送离线消息。因此需判断聊天对象是否在线,即是否在存储用户的通信连接的哈希表_userConnMap中,遍历哈希表查找在线用户id是否为聊天对象id,这里需保证线程安全,加锁

        lock_guard<mutex>lock(_connMutex);
        auto it = _userConnMap.find(to_id);

<1>如果聊天用户在线

服务器作为中转,主动推送消息给聊天对象用户

      if(it!=_userConnMap.end()){
            //to_id在线,转发消息,服务器主动推动消息给to_id用户
            it->second->send(js.dump());
            return ;
        }

<2>如果聊天用户不在线,转而处理离线消息

底层数据库中,有一张offlinemessage表存储了离线消息

与处理user表类似,我们定义offlineMsgModel类处理离线消息业务,实现插入离线消息、删除离线消息、查询离线消息功能

class offlineMsgModel{
    public:
        //存储用户的离线消息
        void insert(int userid,string msg);

        //删除用户的离线消息
        void remove(int userid);

        //查询用户的离线消息
        vector<string> query(int userid);
};

因此,当点对点聊天发现聊天对象不在线时,我们将json对象序列化后存入底层数据库中

因此,存储离线消息函数如下:

// 存储用户的离线消息
void offlineMsgModel::insert(int userid, string msg)
{
    char sql[1024] = {0};
    sprintf(sql, "insert into offlinemessage values(%d, '%s')", userid, msg.c_str());

    MySQL mysql;
    if (mysql.connect())
    {
        mysql.update(sql);
    }
}

(3)第(八)节用户登录模块,用户登录后需查看是否有对应的离线消息,如果有服务器就将数据库中存储的离线消息推送给相应的客户端,然后删除库中存储的离线消息

<1>查看用户是否有离线消息

实现offlineMsgModel的查询函数,用一个vector容器来接收字符串消息

// 查询用户的离线消息
vector<string> offlineMsgModel::query(int userid)
{
    char sql[1024] = {0};
    sprintf(sql, "select message from offlinemessage where userid = %d", userid);

    vector<string> vec;
    MySQL mysql;
    if (mysql.connect())
    {
        MYSQL_RES *res = mysql.query(sql);
        if (res != nullptr)
        {
            // 把userid用户的所有离线消息放入vec中返回
            MYSQL_ROW row;
            while((row = mysql_fetch_row(res)) != nullptr)
            {
                vec.push_back(row[0]);
            }
            mysql_free_result(res);
            return vec;
        }
    }
    return vec;
}
</
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值