Line data Source code
1 : /**
2 : * @file session_manager.cpp
3 : * @brief FIX 会话管理器实现
4 : */
5 :
6 : #include "fix/session_manager.hpp"
7 : #include "base/logger.hpp"
8 :
9 : namespace fix40 {
10 :
11 20 : void SessionManager::registerSession(std::shared_ptr<Session> session) {
12 20 : if (!session) {
13 0 : LOG() << "[SessionManager] Cannot register null session";
14 0 : return;
15 : }
16 :
17 20 : SessionID sessionID = session->get_session_id();
18 :
19 20 : std::lock_guard<std::mutex> lock(mutex_);
20 20 : auto [it, inserted] = sessions_.emplace(sessionID, session);
21 :
22 20 : if (inserted) {
23 18 : LOG() << "[SessionManager] Registered session: " << sessionID.to_string();
24 : } else {
25 : // 替换旧会话
26 2 : it->second = session;
27 2 : LOG() << "[SessionManager] Replaced session: " << sessionID.to_string();
28 : }
29 20 : }
30 :
31 4 : bool SessionManager::unregisterSession(const SessionID& sessionID) {
32 4 : std::lock_guard<std::mutex> lock(mutex_);
33 4 : auto it = sessions_.find(sessionID);
34 4 : if (it != sessions_.end()) {
35 3 : sessions_.erase(it);
36 3 : LOG() << "[SessionManager] Unregistered session: " << sessionID.to_string();
37 3 : return true;
38 : }
39 1 : return false;
40 4 : }
41 :
42 28 : std::shared_ptr<Session> SessionManager::findSession(const SessionID& sessionID) const {
43 28 : std::lock_guard<std::mutex> lock(mutex_);
44 28 : auto it = sessions_.find(sessionID);
45 28 : if (it != sessions_.end()) {
46 13 : return it->second;
47 : }
48 15 : return nullptr;
49 28 : }
50 :
51 13 : bool SessionManager::sendMessage(const SessionID& sessionID, FixMessage& msg) {
52 13 : std::shared_ptr<Session> session = findSession(sessionID);
53 13 : if (!session) {
54 6 : LOG() << "[SessionManager] Cannot send message: session not found "
55 6 : << sessionID.to_string();
56 6 : return false;
57 : }
58 :
59 7 : if (!session->is_running()) {
60 5 : LOG() << "[SessionManager] Cannot send message: session not running "
61 5 : << sessionID.to_string();
62 5 : return false;
63 : }
64 :
65 : try {
66 2 : session->send_app_message(msg);
67 2 : return true;
68 0 : } catch (const std::exception& e) {
69 0 : LOG() << "[SessionManager] Exception sending message: " << e.what();
70 0 : return false;
71 0 : }
72 13 : }
73 :
74 7 : size_t SessionManager::getSessionCount() const {
75 7 : std::lock_guard<std::mutex> lock(mutex_);
76 14 : return sessions_.size();
77 7 : }
78 :
79 7 : bool SessionManager::hasSession(const SessionID& sessionID) const {
80 7 : std::lock_guard<std::mutex> lock(mutex_);
81 14 : return sessions_.find(sessionID) != sessions_.end();
82 7 : }
83 :
84 6 : void SessionManager::forEachSession(
85 : std::function<void(const SessionID&, std::shared_ptr<Session>)> callback) const {
86 6 : std::vector<std::pair<SessionID, std::shared_ptr<Session>>> snapshot;
87 : {
88 6 : std::lock_guard<std::mutex> lock(mutex_);
89 6 : snapshot.reserve(sessions_.size());
90 15 : for (const auto& [id, session] : sessions_) {
91 9 : snapshot.push_back({id, session});
92 : }
93 6 : }
94 :
95 : // 解锁后执行回调,避免回调内重入 SessionManager(例如 sendMessage/unregister)导致死锁。
96 : // 语义说明:遍历使用 snapshot,因此回调执行期间新增/移除的 session 不会反映在本轮遍历中。
97 15 : for (const auto& [id, session] : snapshot) {
98 9 : callback(id, session);
99 : }
100 6 : }
101 :
102 : } // namespace fix40
|