客户端及时通讯系统(1)
编写核心数据结构
- 一、核心数据结构介绍
- 二、将本地新项目推送到gitee已有仓库上
- 三、代码实现
- 3.1 核心数据结构成员变量设计和工具类设计
一、核心数据结构介绍
1)用户信息(UserTnfo)
用户的属性
2)会话信息(ChatSessionInfo)
用户与用户之间的聊天会话
3)消息信息(Message)
文本消息
图片消息
文件消息
语音消息
文本消息,是正文的字符串;图片、文件、语言消息,正文是一个二进制序列。
表示字符串,必须使用QString;表示二进制数据,必须使用QByteArray。
1.我们要创建目录然后创建文件来表示我们的核心类,model是MVC结构里的模型(qt Creator中不方便直接创建,我们就手动创建model)
2.把c++头文件导入到qt里
3.qt的Cmake自动更新文件内容,编译qt文件所需要的依赖(qt_add_executable)
4.命名空间的约定(我设置的当前约定)
1.如果代码所在文件,就是项目的顶层目录中,就直接使用全局的命名空间(不需要手动设置命名空间)
2.如果代码所在文件,在某个子目录中,此时子目录就是文件的命名空间
5.认识static
普通函数:需要把对象构造出来,才能使用普通的函数
加static的函数:不需要先构造函数就可以调用。
6.认识uuid
UUID这个东西,背后是一套算法,就能生成全球唯一的身份标识。
7.认识qDebug
qDebug 打印字符串的时候, 就会自动加上 " “;
qDebug().noquote()可以去除双引号(”")。
二、将本地新项目推送到gitee已有仓库上
在命令窗口中输入:git init
在 Gitee 中 我们刚刚新建的仓库里,去复制仓库的地址
在命令窗口中输入:git remote add origin 你的仓库地址
在命令窗口中输入:git pull origin master
在命令窗口中输入:git add .
在命令窗口中输入:git commit -m “提交项目”
在命令窗口中输入:git push origin master
三、代码实现
3.1 核心数据结构成员变量设计和工具类设计
#pragma once
#include <QString>
#include <QIcon>
#include <QUuid>
#include <QDateTime>
#include <QFile>
#include <QFileInfo>
#include <QDebug>
//创建命名空间
namespace model {
//
/// 工具函数. 后续很多模块可能都要用到
//
static inline QString getFileName(const QString& path) {
QFileInfo fileInfo(path);
return fileInfo.fileName();
}
// 封装一个 "宏" 作为打印日志的方式.
#define TAG QString("[%1:%2]").arg(model::getFileName(__FILE__), QString::number(__LINE__))
// #define TAG "[" << __LINE__ << "]"
// qDebug 打印字符串的时候, 就会自动加上 " "
#define LOG() qDebug().noquote() << TAG
// 要求函数的定义如果写在 .h 中, 必须加 static 或者 inline (当然两个都加也可以), 避免链接阶段出现 "函数重定义" 的问题.
static inline QString formatTime(int64_t timestamp) {
// 先把时间戳, 转换成 QDateTime 对象
QDateTime dateTime = QDateTime::fromSecsSinceEpoch(timestamp);
// 把 QDateTime 对象转成 "格式化时间"
return dateTime.toString("MM-dd HH:mm:ss");
}
// 通过这个函数得到 秒级 的时间
static inline int64_t getTime() {
return QDateTime::currentSecsSinceEpoch();
}
// 根据 QByteArray, 转成 QIcon
static inline QIcon makeIcon(const QByteArray& byteArray) {
//QPixmap提供很多关于图片的处理方法
QPixmap pixmap;
//加载数据
pixmap.loadFromData(byteArray);
QIcon icon(pixmap);
return icon;
}
// 读写文件操作.
// 从指定文件中, 读取所有的二进制内容. 得到一个 QByteArray
static inline QByteArray loadFileToByteArray(const QString& path) {
QFile file(path);
bool ok = file.open(QFile::ReadOnly);
if (!ok) {
LOG() << "文件打开失败!";
return QByteArray();
}
QByteArray content = file.readAll();
file.close();
return content;
}
// 把 QByteArray 中的内容, 写入到某个指定文件里
static inline void writeByteArrayToFile(const QString& path, const QByteArray& content) {
QFile file(path);
bool ok = file.open(QFile::WriteOnly);
if (!ok) {
LOG() << "文件打开失败!";
return;
}
file.write(content);
file.flush();
file.close();
}
/
/// 用户信息
/
//用户信息
class UserInfo{
public:
QString userId = ""; // 用户编号
QString nickname = ""; // 用户昵称
QString description = ""; // 用户签名
QString phone = ""; // 手机号码
QIcon avatar; // 用户头像
};
/
/// 消息信息
/
enum MessageType {
TEXT_TYPE, // 文本消息
IMAGE_TYPE, // 图片消息
FILE_TYPE, // 文件消息
SPEECH_TYPE // 语音消息
};
class Message {
public:
QString messageId = ""; // 消息的编号
QString chatSessionId = ""; // 消息所属会话的编号
QString time = ""; // 消息的时间. 通过 "格式化" 时间的方式来表示. 形如 06-07 12:00:00
MessageType messageType = TEXT_TYPE;// 消息类型
UserInfo sender; // 发送者的信息
QByteArray content; // 消息的正文内容
QString fileId = ""; // 文件的身份标识. 当消息类型为 文件, 图片, 语音 的时候, 才有效. 当消息类型为 文本, 则为 ""
QString fileName = ""; // 文件名称. 只是当消息类型为 文件 消息, 才有效. 其他消息均为 ""
// 此处 extraInfo 目前只是在消息类型为文件消息时, 作为 "文件名" 补充.
static Message makeMessage(MessageType messageType, const QString& chatSessionId, const UserInfo& sender,
const QByteArray& content, const QString& extraInfo) {
if (messageType == TEXT_TYPE) {
return makeTextMessage(chatSessionId, sender, content);
} else if (messageType == IMAGE_TYPE) {
return makeImageMessage(chatSessionId, sender, content);
} else if (messageType == FILE_TYPE) {
return makeFileMessage(chatSessionId, sender, content, extraInfo);
} else if (messageType == SPEECH_TYPE) {
return makeSpeechMessage(chatSessionId, sender, content);
} else {
// 触发了未知的消息类型
return Message();
}
}
private:
// 通过这个方法生成唯一的 messageId
static QString makeId() {
return "M" + QUuid::createUuid().toString().sliced(25, 12);
}
static Message makeTextMessage(const QString& chatSessionId, const UserInfo& sender, const QByteArray& content) {
Message message;
// 此处需要确保, 设置的 messageId 是 "唯一" 的
message.messageId = makeId();
message.chatSessionId = chatSessionId;
message.sender = sender;
message.time = formatTime(getTime()); // 生成一个格式化时间
message.content = content;
message.messageType = TEXT_TYPE;
// 对于文本消息来说, 这俩属性不使用, 设为 ""
message.fileId = "";
message.fileName = "";
return message;
}
static Message makeImageMessage(const QString& chatSessionId, const UserInfo& sender, const QByteArray& content) {
Message message;
message.messageId = makeId();
message.chatSessionId = chatSessionId;
message.sender = sender;
message.time = formatTime(getTime());
message.content = content;
message.messageType = IMAGE_TYPE;
// fileId 后续使用的时候再进一步设置
message.fileId = "";
// fileName 不使用, 直接设为 ""
message.fileName = "";
return message;
}
static Message makeFileMessage(const QString& chatSessionId, const UserInfo& sender, const QByteArray& content, const QString& fileName) {
Message message;
message.messageId = makeId();
message.chatSessionId = chatSessionId;
message.sender = sender;
message.time = formatTime(getTime());
message.content = content;
message.messageType = FILE_TYPE;
// fileId 后续使用的时候进一步设置
message.fileId = "";
message.fileName = fileName;
return message;
}
static Message makeSpeechMessage(const QString& chatSessionId, const UserInfo& sender, const QByteArray& content) {
Message message;
message.messageId = makeId();
message.chatSessionId = chatSessionId;
message.sender = sender;
message.time = formatTime(getTime());
message.content = content;
message.messageType = SPEECH_TYPE;
// fileId 后续使用的时候进一步设置
message.fileId = "";
// fileName 不使用, 直接设为 ""
message.fileName = "";
return message;
}
};
/
/// 会话信息
/
class ChatSessionInfo {
public:
QString chatSessionId = ""; // 会话编号
QString chatSessionName = ""; // 会话名字, 如果会话是单聊, 名字就是对方的昵称; 如果是群聊, 名字就是群聊的名称.
Message lastMessage; // 表示最新的消息.
QIcon avatar; // 会话头像. 如果会话是单聊, 头像就是对方的头像; 如果是群聊, 头像群聊的头像.
QString userId = ""; // 对于单聊来说, 表示对方的用户 id, 对于群聊设为 ""
};
} //end model