添加好友业务代码和测试

87 阅读2分钟

1. 在include/public.hpp中添加加好友消息类型

#ifndef PUBLIC_H
#define PUBLIC_H

// server和client的公共文件
enum EnMsgType
{
    LOGIN_MSG = 1, //登录消息
    LOGIN_MSG_ACK, //登录响应消息
    REG_MSG,       //注册消息
    REG_MSG_ACK,   //注册响应消息
    ONE_CHAT_MSG,  //聊天消息
    ADD_FRIEND_MSG //添加好友消息
};

#endif

2. 数据库层

用户登陆成功会把其好友列表返回回去,实际上好友列表一般是基于客户端的,因为好友列表信息一般比较多,如果每次用户登陆成功以后都通过服务器给用户返回,这样服务器压力太大。因为好友列表又不会变,用户下线后在上线之前好友列表肯定不会变动的,所以在下线的时候就把好友列表全部更新在本地文件,这里使业务更简化就不在本地存了。

我们给用户展现好友列表时,需要返回好友的id、name和state,需要做user表和friend表的联合查询

image.png 表中两个字段,一个是用户id,一个是用户的friend的id,这种关系不用写多次,所以用联合主键,两人是好友写一次就可以了。由于双向的好友关系我们只存储一次(即不能同时存在1-3,3-1),在查询friend表的过滤条件需要查看两个字段userid和friendid,这样才能完整的显示出某个用户的所有好友

SQL语句如下:

select user.id, user.name, user.state from user inner join friend on user.id=friend.friendid where friend.userid=%d

数据库层的include/server/model/friendmodel.hpp如下:

#ifndef FRIENDMODEL_H
#define FRIENDMODEL_H

#include "user.hpp"

#include <vector>
using namespace std;

//维护好友信息的操作接口方法
class FriendModel
{
public:
    //添加好友关系
    void insert(int userid, int friendid);

    //返回用户好友列表
    vector<User> query(int userid);
};

#endif

数据库层的src/server/model/friendmodel.cpp如下:

#include "friendmodel.hpp"
#include "db.h"

//添加好友关系
void FriendModel::insert(int userid, int friendid)
{
    char sql[1024] = {0};

    sprintf(sql, "insert into friend values(%d, %d)", userid, friendid);
    MySQL mysql;

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

//返回用户好友列表
vector<User> FriendModel::query(int userid)
{
    char sql[1024] = {0};
    sprintf(sql, "select user.id, user.name, user.state from user inner join friend on user.id=friend.friendid where friend.userid=%d", userid);

    vector<User> vec;
    MySQL mysql;

    if (mysql.connect())
    {
        MYSQL_RES *res = mysql.query(sql);
        if (res != nullptr)
        {
            MYSQL_ROW row;
            while ((row = mysql_fetch_row(res)) != nullptr)
            {
                User user;
                user.setId(atoi(row[0]));
                user.setName(row[1]);
                user.setState(row[2]);
                vec.push_back(user);
            }
            mysql_free_result(res);
        }
    }
    return vec;
}

3. 业务层

在include/server/chatservice.hpp中添加FriendModel对象和addFriend方法

#include "friendmodel.hpp"
//添加好友业务
void addFriend(const TcpConnectionPtr &conn, json &js, Timestamp);
FriendModel _friendModel;

在src/server/chatservice.cpp中的ChatService构造函数中绑定加好友消息对应的回调函数

image.png chatservice.cpp中实现addFriend方法

//添加好友业务
void ChatService::addFriend(const TcpConnectionPtr &conn, json &js, Timestamp)
{
    int userid = js["userid"].get<int>();
    int friendid = js["friendid"].get<int>();

    //存储好友信息
    _friendModel.insert(userid, friendid);
}

在login方法中实现登录成功后查询用户的好友信息并返回 image.png

4. 编译测试

编译成功后让zhang san登录{"msgid":1,"id":27,"password":"123456"}

image.png zhang san添加li si好友{"msgid":6,"userid":27,"friendid":28},查询数据库friend表

image.png 我们退出zhang san,然后重新登录,看服务器是否能正常返回好友列表

image.png