当前位置: 首页 > article >正文

客户端及时通讯系统(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


http://www.kler.cn/a/573967.html

相关文章:

  • 【YOLOv12改进trick】StarBlock引入YOLOv12,创新涨点优化,含创新点Python代码,方便发论文
  • postman--接口测试工具安装和使用教程
  • LinkedList 双向链表
  • VEC系列-RabbitMQ 入门笔记
  • 快速从C过度C++(一):namespace,C++的输入和输出,缺省参数,函数重载
  • 基于开源 AI 大模型、AI 智能名片及 S2B2C 商城小程序源码的个人 IP 用户运营策略研究
  • 物联网感知层采集的数据 经过etl 后 ,输送给ai 训练模型 和模型本身调优
  • 代码随想录算法训练营第三十九天 | 198.打家劫舍 213.打家劫舍II 337.打家劫舍 III
  • 【Unity】改变游戏运行时Window的窗口标题
  • Java Spring Boot中Model与Entity的区别与联系及多表关联查询的实现
  • 6.过拟合处理:确保模型泛化能力的实践指南——大模型开发深度学习理论基础
  • python+pytest 接口自动化测试:参数关联
  • 【橘子python】在vscode中配置py3
  • 微服务架构下的 Node.js
  • 【Pandas】pandas Series swaplevel
  • ICLR 2025|香港浸会大学可信机器学习和推理课题组专场
  • 大语言模型中Top-K和Top-P是两种核心的文本生成策略
  • 大模型中的剪枝、蒸馏是什么意思?
  • 【Linux】进程信号(终)
  • Magma登场!多模态AI模型,打通数字与物理世界