if(it != _userConnMap.end()){
//用户在线,转发消息
it->second->send(js.dump());
return;
}
}
// 有可能在发送的时候,连接就给断了
// if(userstate){ //用户在线,转发消息
// }
// else{ //用户不在线,存储离线消息
// }
//存储离线消息
_offlineMsgmodel.insert(toid,js.dump());
}
直接聊就这样。
比较复杂一点的是处理离线消息。
开一个专门处理离线消息的文件,offlinemessagemodel.cpp,头文件配上。
#ifndef OFFLINEMESSAGEMODEL_H_
#define OFFLINEMESSAGEMODEL_H_
#include
#include
using namespace std;
class OfflineMessageModel{
public:
//存储用户离线消息
void insert(int user_id,string msg);
//删除用户离线消息
void remove(int userid);
//读取用户离线消息
vector query(int userid);
private:
};
#endif
offlinemessagemodel.cpp 实现:
#include “db.hpp”
#include “offlinemessagemodel.hpp”
//存储用户离线消息
void OfflineMessageModel::insert(int userid, string msg){
char sql[128] = {0};
sprintf(sql, “insert into offlinemessage values(%d, ‘%s’)”, userid, msg.c_str());
MySQL mysql;
if(mysql.connect()){
mysql.update(sql);
}
}
//删除用户离线消息
void OfflineMessageModel::remove(int userid){
char sql[128] = {0};
sprintf(sql,“delete from OfflineMessage where userid = %d”,userid);
MySQL mysql;
if(mysql.connect()){
mysql.update(sql);
}
}
//读取用户离线消息
vector OfflineMessageModel::query(int userid){
// 1.组装sql语句
char sql[1024] = {0};
sprintf(sql, “select message from OfflineMessage where userid = %d”, userid);
vector 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){
vec.push_back(row[0]);
}
mysql_free_result(res);
}
}
return vec;
}
离线消息调用逻辑
1、在发送消息的时候判断对方是否在线,不在线则存储离线消息。
2、在登录的时候加载离线消息,一般消息会很多,所以用容器来存储。
3、容器选择vector,便于直接序列化/反序列化。
第一、三点在上面展示了,第二点:
void ChatService::login(const TcpConnectionPtr &conn,json &js,Timestamp time){
int id = js[“id”].get();
string pwd = js[“password”];
User user = _usermodel.query(id);
if (user.getID() == id && user.getpassword() == pwd)
{
if (user.getstate() == “online”)
{
// 该用户已经登录,不允许重复登录
json response;
response[“msgid”] = LOGIN_MSG_ACK;
response[“errno”] = 2;
response[“errmsg”] = “this account is using, input another!”;
conn->send(response.dump());
}
else
{
//添加作用域,限制锁的粒度
{
lock_guard lock(_connMutex);
//记录用户连接
_userConnMap.insert({id,conn});
}
// 登录成功,更新用户状态信息 state offline=>online
user.setstate(“online”);
_usermodel.updateState(user);
json response;
response[“msgid”] = LOGIN_MSG_ACK;
response[“errno”] = 0;
response[“id”] = user.getID();
response[“name”] = user.getname();