221 lines
6.1 KiB
C++
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;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|