C++搭建集群聊天室(十四):群聊功能
Posted 看,未来
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++搭建集群聊天室(十四):群聊功能相关的知识,希望对你有一定的参考价值。
群聊功能思路
1、创建群聊,提交群信息,返回群号
2、拉取群人员基本信息,包括昵称、ID。
3、群发消息时,如果成员在线则直接推送,成员不在线则存储相应群员的离线消息。
放码过来
照例先修改一下 public.hpp 文件。
#ifndef PUBLIC_H_
#define PUBLIC_H_
enum EnMsgType{
LOGIN_TYPE = 1, //正常登录
LOGIN_MSG_ACK, //登录相应消息
REG_TYPE, //正常注册
REG_MSG_ACK, //注册相应消息
ONE_CHAT_MSG, //一对一聊天消息
ADD_FRINEND_MSG,//添加好友
CREATE_GROUP_MSG, // 创建群组
ADD_GROUP_MSG, // 加入群组
GROUP_CHAT_MSG, // 群聊天
};
#endif
成员基本信息和 User 重合度高,所以直接继承 User 类。
groupuser.hpp
#ifndef GROUPUSER_H
#define GROUPUSER_H
#include "user.hpp"
// 群组用户,多了一个role角色信息,从User类直接继承,复用User的其它信息
class GroupUser : public User
{
public:
void setRole(string role) { this->role = role; }
string getRole() { return this->role; }
private:
string role;
};
#endif
group.hpp
这个文件映射的是 AllGroup 的数据表。
#ifndef GROUP_H
#define GROUP_H
#include "groupuser.hpp"
#include <string>
#include <vector>
using namespace std;
// GroupUser表的映射
class Group
{
public:
Group(int id = -1, string name = "", string desc = "")
{
this->id = id;
this->name = name;
this->desc = desc;
}
void setId(int id) { this->id = id; }
void setName(string name) { this->name = name; }
void setDesc(string desc) { this->desc = desc; }
int getId() { return this->id; }
string getName() { return this->name; }
string getDesc() { return this->desc; }
vector<GroupUser> &getUsers() { return this->users; }
private:
int id;
string name;
string desc;
vector<GroupUser> users;
};
#endif
接下来,是model类的声明及其实现。
groupmodel.hpp
#ifndef GROUPMODEL_H_
#define GROUPMODEL_H_
#include "group.hpp"
#include <string>
#include <vector>
using namespace std;
// 维护群组信息的操作接口方法
class GroupModel
{
public:
// 创建群组
bool createGroup(Group &group);
// 加入群组
void addGroup(int userid, int groupid, string role);
// 查询用户所在群组信息
vector<Group> queryGroups(int userid);
// 根据指定的groupid查询群组用户id列表,除userid自己,主要用户群聊业务给群组其它成员群发消息
vector<int> queryGroupUsers(int userid, int groupid);
};
#endif
groupmodel.cpp
#include "groupmodel.hpp"
#include "db.hpp"
// 创建群组
bool GroupModel::createGroup(Group &group)
{
// 1.组装sql语句
char sql[1024] = {0};
sprintf(sql, "insert into AllGroup(groupname, groupdesc) values('%s', '%s')",group.getName().c_str(), group.getDesc().c_str());
mysql mysql;
if (mysql.connect())
{
if (mysql.update(sql))
{
group.setId(mysql_insert_id(mysql.getconnection()));
return true;
}
}
return false;
}
// 加入群组
void GroupModel::addGroup(int userid, int groupid, string role)
{
// 1.组装sql语句
char sql[1024] = {0};
sprintf(sql, "insert into groupuser values(%d, %d, '%s')",
groupid, userid, role.c_str());
MySQL mysql;
if (mysql.connect())
{
mysql.update(sql);
}
}
// 查询用户所在群组信息
vector<Group> GroupModel::queryGroups(int userid)
{
// 根据userid在groupuser表中查询出该用户所属的群组信息
char sql[1024] = {0};
sprintf(sql, "select a.id,a.groupname,a.groupdesc from allgroup a inner join groupuser b on a.id = b.groupid where b.userid=%d",userid);
vector<Group> groupVec;
MySQL mysql;
if (mysql.connect())
{
MYSQL_RES *res = mysql.query(sql);
if (res != nullptr)
{
MYSQL_ROW row;
// 查出userid所有的群组信息
while ((row = mysql_fetch_row(res)) != nullptr)
{
Group group;
group.setId(atoi(row[0]));
group.setName(row[1]);
group.setDesc(row[2]);
groupVec.push_back(group);
}
mysql_free_result(res);
}
}
// 根据群组信息,查询属于该群组的所有用户的userid,并且和user表进行多表联合查询,查出用户的详细信息
for (Group &group : groupVec)
{
sprintf(sql, "select a.id,a.name,a.state,b.grouprole from user a inner join groupuser b on b.userid = a.id where b.groupid=%d",group.getId());
MYSQL_RES *res = mysql.query(sql);
if (res != nullptr)
{
MYSQL_ROW row;
// 对 group 中 user 字段进行填充
while ((row = mysql_fetch_row(res)) != nullptr)
{
GroupUser user;
user.setID(atoi(row[0]));
user.setname(row[1]);
user.setstate(row[2]);
user.setRole(row[3]);
group.getUsers().push_back(user);
}
mysql_free_result(res);
}
}
return groupVec;
}
// 根据指定的groupid查询群组用户id列表,就是上面功能中的一小块儿剥离出来
// 用于消息群发
vector<int> GroupModel::queryGroupUsers(int userid, int groupid)
{
char sql[1024] = {0};
sprintf(sql, "select userid from groupuser where groupid = %d and userid != %d", groupid, userid);
vector<int> idVec;
MySQL mysql;
if (mysql.connect())
{
MYSQL_RES *res = mysql.query(sql);
if (res != nullptr)
{
MYSQL_ROW row;
while ((row = mysql_fetch_row(res)) != nullptr)
{
idVec.push_back(atoi(row[0]));
}
mysql_free_result(res);
}
}
return idVec;
}
一切准备妥当,至此我们的单台服务器开发完成。
调整一下代码版块,把model层代码放到model模块中,再修改一下cmake。
以上是关于C++搭建集群聊天室(十四):群聊功能的主要内容,如果未能解决你的问题,请参考以下文章