IM/MS/mmm/session.cpp
2023-07-04 14:10:13 +08:00

221 lines
6.1 KiB
C++

//
// Created by dongl on 23-5-10.
//
#include <arpa/inet.h>
#include <thread>
#include "../MS.h"
#include "session.h"
//std::map<uint64_t, userinfo*> session::user_fd;
//std::map<bufferevent*, std::map<std::string, std::string>> session::session_map;
session::session() {
printf("timing begin\n");
timing();
printf("timing end\n");
}
session::session(session_build_type type) {
if (type == SESSION_SUPPORT_ALL) {
printf("timing begin\n");
timing();
printf("timing end\n");
} else if (type == SESSION_SUPPORT_SESSION) {
printf("timing begin\n");
timing();
printf("timing end\n");
}
else if (type == SESSION_SUPPORT_USER) {
}
}
/// curr mem user curd user session
void session::add_user(mp::sri* sri, std::shared_ptr<agreement_request>& request) {
if (sri->subcommand() == mp::MP_LOGIN_SUCCESS) {
auto ele = new userinfo();
ele->bev = request->m_bev;
sprintf(ele->ip, "%s", inet_ntoa(request->m_addr->sin_addr));
user_fd.insert({strtol(request->m_body.account().c_str(), nullptr, 0), ele});
}
}
void session::remove_user(bufferevent *bev) {
uint64_t target_ele = -1;
for (const auto &item: user_fd) {
if (bev == item.second->bev) {
target_ele = item.first;
break;
}
}
// 还未登陆就不删除user
if (target_ele != -1) {
user_fd.erase(target_ele);
}
bufferevent_free(bev);
}
void session::remove_user(const std::shared_ptr<agreement_request>& request) {
user_fd.erase(strtol(request->m_body.account().c_str(), nullptr, 0));
bufferevent_free(request->m_bev);
}
bool session::is_user(uint64_t account) {
if( user_fd.find(account) == user_fd.cend() ){
return false;
}
return true;
}
bool session::is_user(const std::string& account) {
return session::is_user(strtol(account.c_str(), nullptr, 0));
}
std::optional<std::pair<uint64_t, userinfo*>> session::find_user_fd(uint64_t account) {
auto ret = user_fd.find(account);
if (ret != user_fd.cend()) {
return {{ret->first, ret->second} };
} else {
return std::nullopt;
}
}
/// user bev fd lik session
void session::init_session(bufferevent *bev) {
std::map<std::string, std::string> sub_session;
session_map.insert({bev, sub_session});
}
// 给用户 添加会话信息
void session::set_session(bufferevent* bev, const std::string &session_key, const std::string &session_value) {
printf("code: %s\n", session_value.c_str());
auto ret = session_map.find(bev);
// 先看有没有 bev session 没有初始化并且添加一个 有取出来sub session 在添加
if (ret == session_map.cend()) {
std::map<std::string, std::string> sub_session;
sub_session.insert({session_key, session_value});
session_map.insert({bev, sub_session});
} else {
ret->second.insert({session_key, session_value});
}
/// map 内部自动排序 添加 时间 要删除信息的链表
// 添加时间轮 定时器
time_t t = time(nullptr);
auto retwheel = session_time_wheel.find(t);
std::list<bev_key*> list;
// 看看 此时间点 有没有 任务
if (retwheel != session_time_wheel.cend()) {
list = session_time_wheel.find(t)->second;
}
auto bk = new bev_key();
bk->bev = bev;
bk->key = session_key;
bk->value = session_value;
list.emplace_back(bk);
session_time_wheel.insert({t, list});
}
// 给用户 查询会话信息
std::optional<std::string> session::get_session(bufferevent* bev, const std::string &session_key) {
auto sess = session_map.find(bev);
if (sess != session_map.cend()) {
auto ret = sess->second.find(session_key);
if (ret != sess->second.cend()) {
return ret->second;
}
}
return std::nullopt;
}
void session::remove_session(bufferevent *bev, const std::string &session_key) {
auto ret = session_map.find(bev);
if (ret != session_map.cend()) {
auto sub = ret->second.find(session_key);
if (sub != ret->second.cend()) {
ret->second.erase(sub);
}
}
// 同时删除时间轮内的 注册session
// 这里的实现 太垃圾了
bool remove_state = false;
std::list<bev_key>::iterator iterator;
for (const auto &item: session_time_wheel) {
for (auto mem = item.second.begin(); mem != item.second.end(); ++mem) {
if (mem.operator*()->key == session_key) {
auto i = item.second;
i.remove(mem.operator*());
if (i.empty()) {
session_time_wheel.erase(item.first);
remove_state = true;
}
break;
}
}
if (remove_state) {
break;
}
}
}
void session::remove_session(userinfo *user) {
}
// 时间轮思路的 定时器
void session::timing() {
auto pool = MS::localEvPool();
pool->add_event_base([&]() {
while (true) {
while (!session_time_wheel.empty()) {
auto wheel = session_time_wheel.begin();
printf("session ");
for (const auto &item: wheel->second) {
printf("bev:%p, key:%s, value:%s", item->bev, item->key.c_str(), get_session(item->bev, item->key).value().c_str());
}
printf("\n");
if (wheel->first > time(nullptr) + 300000) { // 5分钟
// 超时5分钟就删除
for (const auto &item: wheel->second) {
remove_session(item->bev, item->key);
}
}
// printf("timing %ld\n", wheel->first);
std::this_thread::sleep_for(std::chrono::seconds(1));
break;
}
std::this_thread::sleep_for(std::chrono::seconds(1));
}
});
}
std::optional<userinfo*> session::find_user(uint64_t account) {
auto temp = user_fd.find(account);
if (temp == user_fd.cend()) {
return std::nullopt;
} else {
return temp->second;
}
}