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

[集群聊天服务器]----(七)业务模块之一对一聊天、添加好友函数、好友类以及离线消息类

接着[集群聊天服务器]----(六)业务模块之用户注册、登录、退出以及客户端异常退出函数中对于业务模块的用户注册、登录、退出以及客户端异常退出函数的剖析,现在我们对点对点聊天以及添加好友的实现进行剖析。

点对点聊天

当客户端输入msgid=ONE_CHAT_MSG时,ChatService::ChatService()中会回调ChatService::oneChat()函数进行处理

void ChatService::oneChat(const TcpConnectionPtr &conn, json &js, Timestamp time)
{int toid = js["toid"].get<int>(); // 对方的id{//在一台主机上lock_guard<mutex> lock(_connMutex); // 线程安全auto it = _userConnMap.find(toid);if (it != _userConnMap.end()){// toid 在线 转发消息 服务器主动推送消息给toid用户it->second->send(js.dump());return;}}// 查询toid是否在线User user = _userModel.query(toid);//在另一台电脑上if (user.getState() == "online"){_redis.publish(toid, js.dump());return;}// toid 不在线 存储离线消息_offlineMsgModel.insert(toid, js.dump());
}
  • 通过 JSON 对象反序列结果,寻找toid对应的值,找到用户想要对话的用户,并在_userConnMap中进行查找是否有此对象;
  • 如果用户在一台主机并且处于在线状态,就发送想要发送的消息;
  • 如果不在同一台主机,根据toid调用_userModel在user表中进行查看对方是否在线,如果在线就通过redis发布消息
  • 不在线就存储其离线消息

添加好友

当客户端输入msgid=ADD_FRIEND_MSG时,ChatService::ChatService()中会回调ChatService::addFriend()函数进行处理

void ChatService::addFriend(const TcpConnectionPtr &conn, json &js, Timestamp time)
{int userid = js["id"].get<int>();int friendid = js["friendid"].get<int>();// 存储好友信息_friendModel.insert(userid, friendid);
}
  • 根据客户端获取的用户id以及想要添加的好友id,在好友表中进行存储;

好友消息FriendModel

//添加好友关系
void insert(int userid, int friendid);//返回用户好友列表 friendid=>friendname id
vector<User> query(int userid);

添加好友关系

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);}
}
  • 组装sql语句,根据用户id以及好友id( userid, friendid),在friend表中进行更改

返回用户好友列表

vector<User> FriendModel::query(int userid)
{char sql[1024] = {0};sprintf(sql, "select a.id,a.name,a.state from user a inner join friend b on b.friendid = a.id where b.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;}}return vec;}
  • 组装sql语句,根据userid在user 和 friend表进行联合查询好友的id name state
  • 根据sql语句,调用MySQL::query()语句进行查找好友,然后调用mysql_fetch_row()函数,查找对应的行,rowMYSQL_ROW类型,可以根据下标找到对应的值,并把id name state放入vec中返回
  • 注意释放资源

离线消息类OfflineMsgModel

//存储用户的离线消息
void insert(int userid, string msg);//删除用户的离线消息
void remove(int userid);//查询用户的离线消息
vector<string> query(int userid);

存储用户的离线消息

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);}
}
  • 组装sql语句,根据userid像offlinemessage表中添加离线消息msg
  • 连接数据库,并进行更新

删除用户的离线消息

在用户登录以后,需要显示离线消息,并删除用户的离线消息表

void OfflineMsgModel::remove(int userid)
{char sql[1024] = {0};sprintf(sql, "delete from offlinemessage where userid=%d", userid);MySQL mysql;// 连接数据库if (mysql.connect()){// 更新数据库语句mysql.update(sql);}
}
  • 组装sql语句,根据userid在offlinemessage表中删除相关消息
  • 连接数据库,并进行更新

查询用户的离线消息

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;
}
  • 组装sql语句,根据userid在offlinemessage表查找离线消息;
  • 根据sql语句,调用MySQL::query()语句进行查找好友,然后调用mysql_fetch_row()函数,查找对应的行,rowMYSQL_ROW类型,可以根据下标找到对应的值,并把离线消息放入vec中返回
  • 注意释放资源

好了~ 关于业务模块的一对一聊天、添加好友函数、好友类以及离线消息类的剖析就到此结束了,下一节我们将对群组进行剖析,下一节见~~

相关文章:

[集群聊天服务器]----(七)业务模块之一对一聊天、添加好友函数、好友类以及离线消息类

接着[集群聊天服务器]----(六)业务模块之用户注册、登录、退出以及客户端异常退出函数中对于业务模块的用户注册、登录、退出以及客户端异常退出函数的剖析&#xff0c;现在我们对点对点聊天以及添加好友的实现进行剖析。 点对点聊天 当客户端输入msgidONE_CHAT_MSG时&#x…...

java中使用jedis连接redis

4.java中使用jedis连接redis...

【多线程开发 2】从代码到实战TransmittableThreadLocal

【多线程开发 2】从代码到实战TransmittableThreadLocal 本文将从以下几个点讲解TransmittableThreadLocal(为了方便写以下简称ttl)&#xff1a; 前身 是什么&#xff1f; 可以用来做什么&#xff1f; 源码原理 实战 前身 ThreadLocal 要了解ttl就要先了解Java自带的类…...

【车载以太网测试从入门到精通】——SOME/IP协议测试

系列文章目录 【车载以太网测试从入门到精通】系列文章目录汇总 文章目录 系列文章目录前言一、SOME/IP时间参数1.INITIAL_DELAY时间2.REPETITIONS_MAX次数3.REPETITIONS_BASE_DELAY时间4.CYCLIC_OFFER_DELAY时间5.TIME_TO_LIVE时间6.SUBSCRIBE_RETRY_DELAY时间二、SOME/IP服务…...

作业39 sqrt应用

目录 判断完全平方数 题目描述 输出所有因数 题目描述 因子求和 题目描述 判断素数 题目描述 判断完全平方数 题目描述 输入一个整数&#xff0c;判断他是否是完全平方数&#xff0c;如果是&#xff0c;输出yes&#xff0c;否则输出no 样例 样例…...

springboot 实现跨域的几种方式

1、跨域的原因&#xff1a; 由于同源策略(Same Origin Policy)的限制,浏览器不允许跨域请求。同源策略规定,A网页设置的Cookie、LocalStorage和IndexDB无法被同源以外的网页读取。 2、原因&#xff1a; 1&#xff09;浏览器的同源策略(Same Origin Policy)限制了跨域请求。主要…...

springmvc Web上下文初始化

Web上下文初始化 web上下文与SerlvetContext的生命周期应该是相同的&#xff0c;springmvc中的web上下文初始化是由ContextLoaderListener来启动的 web上下文初始化流程 在web.xml中配置ContextLoaderListener <listener> <listener-class>org.springframework.…...

Verilog实战学习到RiscV - 2 : wire 和 reg 的区别

Verilog: wire 和 reg 的区别 1 引言 看Verilog例子过程中&#xff0c;总是分不清 wire 和 reg 的区别。这篇文章把两者放在一起总结一下&#xff0c;并且对比何时使用它们。 1.1 wire &#xff1a;组合逻辑 wire 是 Verilog 设计中的简单导线&#xff08;或任意宽度的总线…...

OpenGL给定直线起点和终点不同的颜色,使用中点Bresenham画线

用鼠标左键按下确定直线起点&#xff0c;鼠标左键抬起确定直线终点。放一部分代码。 // 中点Bresenham算法.cpp : 定义控制台应用程序的入口点。 //#include "stdafx.h" #include <GL/glut.h> #include <iostream> #include <cmath>int windowWidt…...

IT行业的现状与未来发展趋势:从云计算到量子计算的技术变革

随着技术的不断进步&#xff0c;IT行业已经成为推动全球经济和社会发展的关键力量。从云计算、大数据、人工智能到物联网、5G通信和区块链&#xff0c;这些技术正在重塑我们的生活和工作方式。本文将深入探讨当前IT行业的现状&#xff0c;并展望未来发展趋势&#xff0c;旨在为…...

电脑远程控制另一台电脑怎么弄?

可以远程控制另一台电脑吗&#xff1f; “你好&#xff0c;我对远程访问技术不太了解。现在&#xff0c;我希望我的朋友可以远程控制我的Windows 10电脑&#xff0c;以便她能帮我解决一些问题。请问&#xff0c;有没有免费的方法可以实现这种远程控制&#xff1f;我该如何操作…...

软件设计师备考 | 案例专题之面向对象设计 概念与例题

相关概念 关系 依赖&#xff1a;一个事物的语义依赖于另一个事物的语义的变化而变化 关联&#xff1a;一种结构关系&#xff0c;描述了一组链&#xff0c;链是对象之间的连接。分为组合和聚合&#xff0c;都是部分和整体的关系&#xff0c;其中组合事物之间关系更强。两个类之…...

UniApp 2.0可视化开发工具:引领前端开发新纪元

一、引言 在移动互联网迅猛发展的今天&#xff0c;移动应用开发已经成为前端开发的重要方向之一。为了简化移动应用开发流程&#xff0c;提高开发效率&#xff0c;各大开发平台不断推出新的工具和框架。UniApp作为一款跨平台的移动应用开发框架&#xff0c;自诞生以来就备受开…...

前端调用浏览器录音功能且生成文件(vue)

如果可以实现记得点赞分享&#xff0c;谢谢老铁&#xff5e; 首先在页面中给两个按钮&#xff0c;分别是“开始录音”&#xff0c;“结束录音”。以及录音成功后生成一个下载语音的链接。 1. 先看页面展示 <template><div><button click"startRecording…...

「大数据」Kappa架构

Kappa架构是一种处理大数据的架构&#xff0c;它作为Lambda架构的替代方案出现。Kappa架构的核心思想是简化数据处理流程&#xff0c;通过使用单一的流处理层来同时处理实时和批量数据&#xff0c;从而避免了Lambda架构中需要维护两套系统&#xff08;批处理层和速度层&#xf…...

详细分析Element Plus中的ElMessageBox弹窗用法(附Demo及模版)

目录 前言1. 基本知识2. Demo3. 实战4. 模版 前言 由于需要在登录时&#xff0c;附上一些用户说明书的弹窗 对于ElMessageBox的基本知识详细了解 可通过官网了解基本的语法知识ElMessageBox官网基本知识 1. 基本知识 Element Plus 是一个基于 Vue 3 的组件库&#xff0c;其中…...

Python自动化工具(桌面自动化、Web自动化、游戏辅助)

工具介绍 连点工具是一款可以模拟键鼠后台操作的连点器工具。支持鼠标连点、键鼠脚本录制&#xff0c;支持辅助您实现办公自动化以及辅助游戏操作。功能简洁易用&#xff0c;非常方便操作。连点工具让您在在玩游戏、网购抢购的时候全自动点击鼠标&#xff01;主要功能有&#…...

opencv进阶 ——(五)图像处理之马赛克

一、遍历图像并对每个马赛克区域进行像素化处理 for (int y 0; y < image.rows; y blockSize) {for (int x 0; x < image.cols; x blockSize) {cv::Rect rect cv::Rect(x, y, std::min(blockSize, image.cols - x), std::min(blockSize, image.rows - y));cv::Scal…...

电机控制系列模块解析(22)—— 零矢量刹车

一、零矢量刹车 基本概念 逆变器通常采用三相桥式结构&#xff0c;包含六个功率开关元件&#xff08;如IGBT或MOSFET&#xff09;&#xff0c;分为上桥臂和下桥臂。每个桥臂由两个反并联的开关元件组成&#xff0c;上桥臂和下桥臂对应于电机三相绕组的正负端。正常工作时&…...

自定义一个SpringBoot场景启动器

前言 一个刚刚看完SpringBoot自动装配原理的萌新依据自己的理解写下的文章&#xff0c;如有大神发现错误&#xff0c;敬请斧正&#xff0c;不胜感激。 分析SpringBoot自动配置原理 SpringBoot的启动从被SpringBootApplication修饰的启动类开始,SpringBootApplicaiotn注解中最…...

64_《智能体微服务架构企业级实战教程》授权与认证之授权认证集成测试

前言 配套视频教程: 在 Bilibili课堂、CSDN课程、51CTO学堂 同步发售,提供:源码+部署脚本+文档。 bilibili课堂视频教程:智能体微服务架构企业级实战教程_哔哩哔哩_bilibili CSDN课程视频教程:智能体微服务架构企业级实战教程_在线视频教程-CSDN程序员研修院 51CTO学堂…...

IPD的势、道、法、术、器

目录 简介 一、势&#xff1a;为什么 IPD 是必然选择&#xff1f; 二、道&#xff1a;IPD 的底层哲学 三、法与术&#xff1a;从战略到执行的具体路径 四、器&#xff1a;让流程真正落地的工具与组织 不是每家公司都需要全套 IPD&#xff0c;但每家公司都需要 IPD 思维 简…...

从社交关系到分子结构:图解GCN(图卷积网络)到底在‘看’什么?

从社交关系到分子结构&#xff1a;图解GCN&#xff08;图卷积网络&#xff09;到底在‘看’什么&#xff1f;想象一下&#xff0c;你刚搬到一个新社区&#xff0c;想快速了解周围的邻居。最直接的方式是什么&#xff1f;不是挨家挨户敲门&#xff0c;而是通过社区活动认识几位关…...

Agent开发面试通关攻略:吃透稳拿offer

阅读前置&#xff1a;2026年当下最卷也最缺人的AI岗位&#xff0c;一定是AI Agent开发。最近刷遍CSDN、牛客、力扣最新面经&#xff0c;发现一个非常明显的招聘趋势&#xff1a;普通大模型微调岗位饱和内卷&#xff0c;而AI Agent开发岗位人才严重缺口&#xff0c;薪资更高、竞…...

千亿镁合金产业集群正在成形:成都、抚州、池州的新版图

一个新赛道的地理坐标 如果要在中国地图上标注一条正在成形的新兴产业集群走廊&#xff0c;高强镁合金这条线&#xff0c;值得被认真画出来。 成都龙泉驿——江西抚州临川——安徽池州高新区&#xff0c;三个坐标&#xff0c;三条生产线&#xff0c;一家公司&#xff0c;两年内…...

武汉国电华美16875kVA串联谐振试验装置,这手活儿细

在超高压变电站和长距离电缆的现场&#xff0c;交流耐压试验是检验设备绝缘的“最后一关”。这位老师傅经手过不少大工程&#xff0c;他说&#xff0c;面对GIS、大型变压器这些“大块头”电容性试品&#xff0c;能不能顺利“过关”&#xff0c;往往就看串联谐振装置顶不顶得住。…...

3个步骤彻底解决WSA安装失败问题:从错误代码到完美运行

3个步骤彻底解决WSA安装失败问题&#xff1a;从错误代码到完美运行 【免费下载链接】WSABuilds Run Windows Subsystem For Android on your Windows 10 and Windows 11 PC using prebuilt binaries with Google Play Store (MindTheGapps) and/or Magisk or KernelSU (root so…...

如何高效实现Windows自动化鼠标点击:AutoClicker完整实战指南

如何高效实现Windows自动化鼠标点击&#xff1a;AutoClicker完整实战指南 【免费下载链接】AutoClicker AutoClicker is a useful simple tool for automating mouse clicks. 项目地址: https://gitcode.com/gh_mirrors/au/AutoClicker AutoClicker是一款专业的Windows桌…...

2026上海GEO生成式引擎优化服务商综合实力测评:谁在真正帮品牌进入AI答案

当企业在讨论“上海生成式引擎优化公司哪家好”时&#xff0c;这个问题本身就反映了市场一个关键的转折。两三年前&#xff0c;企业营销的主战场还是搜索引擎排名和官网访问量。现在&#xff0c;决策者开始频繁向DeepSeek、豆包、通义千问等AI工具提问&#xff0c;而这些生成式…...

三分钟快速上手:FanControl让你的电脑风扇从此安静又高效

三分钟快速上手&#xff1a;FanControl让你的电脑风扇从此安静又高效 【免费下载链接】FanControl.Releases This is the release repository for Fan Control, a highly customizable fan controlling software for Windows. 项目地址: https://gitcode.com/GitHub_Trending…...