LCOV - code coverage report
Current view: top level - include/fix - application.hpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 61.1 % 18 11
Test Date: 2025-12-19 03:13:09 Functions: 54.5 % 11 6

            Line data    Source code
       1              : /**
       2              :  * @file application.hpp
       3              :  * @brief FIX 应用层接口定义
       4              :  *
       5              :  * 定义业务逻辑与会话层的分离接口,允许用户实现自定义的
       6              :  * 业务消息处理逻辑,而无需修改底层会话管理代码。
       7              :  */
       8              : 
       9              : #pragma once
      10              : 
      11              : #include <string>
      12              : #include <functional>
      13              : #include "fix/fix_codec.hpp"
      14              : 
      15              : namespace fix40 {
      16              : 
      17              : // 前置声明
      18              : class Session;
      19              : class IStore;
      20              : 
      21              : /**
      22              :  * @struct SessionID
      23              :  * @brief FIX 会话标识符
      24              :  *
      25              :  * 唯一标识一个 FIX 会话,由发送方和接收方的 CompID 组成。
      26              :  * 用于在多会话环境中区分不同的连接。
      27              :  */
      28              : struct SessionID {
      29              :     std::string senderCompID;  ///< 发送方标识符
      30              :     std::string targetCompID;  ///< 接收方标识符
      31              : 
      32              :     /**
      33              :      * @brief 默认构造函数
      34              :      */
      35         2754 :     SessionID() = default;
      36              : 
      37              :     /**
      38              :      * @brief 构造会话标识符
      39              :      * @param sender 发送方 CompID
      40              :      * @param target 接收方 CompID
      41              :      */
      42           83 :     SessionID(const std::string& sender, const std::string& target)
      43           83 :         : senderCompID(sender), targetCompID(target) {}
      44              : 
      45              :     /**
      46              :      * @brief 转换为字符串表示
      47              :      * @return std::string 格式为 "sender->target"
      48              :      */
      49           77 :     std::string to_string() const {
      50          154 :         return senderCompID + "->" + targetCompID;
      51              :     }
      52              : 
      53              :     /**
      54              :      * @brief 相等比较
      55              :      */
      56           28 :     bool operator==(const SessionID& other) const {
      57           56 :         return senderCompID == other.senderCompID && 
      58           56 :                targetCompID == other.targetCompID;
      59              :     }
      60              : 
      61              :     /**
      62              :      * @brief 不等比较
      63              :      */
      64            1 :     bool operator!=(const SessionID& other) const {
      65            1 :         return !(*this == other);
      66              :     }
      67              : };
      68              : 
      69              : /**
      70              :  * @class Application
      71              :  * @brief FIX 应用层抽象接口
      72              :  *
      73              :  * 该接口将业务逻辑与 FIX 会话层分离。Session 负责处理会话层消息
      74              :  * (Logon、Logout、Heartbeat、TestRequest),而业务消息(如订单、
      75              :  * 执行报告等)则委托给 Application 实现类处理。
      76              :  *
      77              :  * @par 回调分类
      78              :  * - 业务消息回调:fromApp / toApp
      79              :  * - 管理消息回调:fromAdmin / toAdmin
      80              :  * - 生命周期回调:onLogon / onLogout
      81              :  *
      82              :  * @par 线程安全
      83              :  * @warning Application 的回调方法可能被多个工作线程并发调用!
      84              :  * 
      85              :  * 由于 FixServer 使用线程池,不同客户端连接绑定到不同工作线程,
      86              :  * 当多个客户端同时发送消息时,fromApp() 会被并发调用。
      87              :  * 
      88              :  * 推荐的线程安全实现方式:
      89              :  * 1. fromApp() 只做轻量操作:将消息封装后 push 到无锁队列
      90              :  * 2. 由独立的业务处理线程(如撮合引擎)从队列消费并处理
      91              :  * 3. 避免在 fromApp() 中执行耗时操作或持有锁
      92              :  *
      93              :  * @par 异常处理
      94              :  * Session 会捕获 Application 回调中抛出的异常,记录日志后继续运行。
      95              :  * 但强烈建议在 Application 实现中自行处理异常,避免依赖外部捕获。
      96              :  *
      97              :  * @par 生命周期
      98              :  * Application 实例的生命周期应由 Server/Client 管理,
      99              :  * 且必须比关联的 Session 更长。Session 仅持有裸指针。
     100              :  *
     101              :  * @par 使用示例
     102              :  * @code
     103              :  * class MyTradingApp : public Application {
     104              :  * public:
     105              :  *     void onLogon(const SessionID& sessionID) override {
     106              :  *         LOG() << "Session logged on: " << sessionID.to_string();
     107              :  *     }
     108              :  *     
     109              :  *     void fromApp(const FixMessage& msg, const SessionID& sessionID) override {
     110              :  *         // 推荐:只做轻量操作,push 到队列
     111              :  *         order_queue_.enqueue({msg, sessionID});
     112              :  *     }
     113              :  * };
     114              :  * @endcode
     115              :  */
     116              : class Application {
     117              : public:
     118              :     /**
     119              :      * @brief 虚析构函数
     120              :      */
     121           34 :     virtual ~Application() = default;
     122              : 
     123              :     // =========================================================================
     124              :     // 生命周期回调
     125              :     // =========================================================================
     126              : 
     127              :     /**
     128              :      * @brief 会话登录成功回调
     129              :      * @param sessionID 已建立的会话标识符
     130              :      *
     131              :      * 当 FIX 会话成功建立(收到 Logon 确认)后调用。
     132              :      * 可用于初始化交易状态、订阅行情等。
     133              :      *
     134              :      * @note 可能被多个工作线程并发调用
     135              :      */
     136              :     virtual void onLogon(const SessionID& sessionID) = 0;
     137              : 
     138              :     /**
     139              :      * @brief 会话登出回调
     140              :      * @param sessionID 即将断开的会话标识符
     141              :      *
     142              :      * 当 FIX 会话即将断开(收到 Logout 或连接关闭)时调用。
     143              :      * 可用于清理交易状态、取消未完成订单等。
     144              :      *
     145              :      * @note 可能被多个工作线程并发调用
     146              :      */
     147              :     virtual void onLogout(const SessionID& sessionID) = 0;
     148              : 
     149              :     // =========================================================================
     150              :     // 业务消息回调
     151              :     // =========================================================================
     152              : 
     153              :     /**
     154              :      * @brief 收到业务消息回调
     155              :      * @param msg 收到的 FIX 业务消息
     156              :      * @param sessionID 消息来源的会话标识符
     157              :      *
     158              :      * 当收到非会话层消息(MsgType 不是 A/0/1/5)时调用。
     159              :      * 典型的业务消息包括:
     160              :      * - D: NewOrderSingle(新订单)
     161              :      * - F: OrderCancelRequest(撤单请求)
     162              :      * - 8: ExecutionReport(执行报告)
     163              :      *
     164              :      * @warning 可能被多个工作线程并发调用!
     165              :      * 推荐实现:只做轻量操作,将消息 push 到无锁队列
     166              :      */
     167              :     virtual void fromApp(const FixMessage& msg, const SessionID& sessionID) = 0;
     168              : 
     169              :     /**
     170              :      * @brief 发送业务消息前回调
     171              :      * @param msg 即将发送的 FIX 业务消息(可修改)
     172              :      * @param sessionID 发送消息的会话标识符
     173              :      *
     174              :      * 在业务消息发送前调用,可用于:
     175              :      * - 记录审计日志
     176              :      * - 添加/修改字段
     177              :      * - 消息验证
     178              :      *
     179              :      * 默认实现为空,子类可选择性重写。
     180              :      *
     181              :      * @note 可能被多个工作线程并发调用
     182              :      */
     183            0 :     virtual void toApp(FixMessage& msg, const SessionID& sessionID) {
     184              :         (void)msg;
     185              :         (void)sessionID;
     186            0 :     }
     187              : 
     188              :     // =========================================================================
     189              :     // 管理消息回调(可选)
     190              :     // =========================================================================
     191              : 
     192              :     /**
     193              :      * @brief 收到管理消息回调
     194              :      * @param msg 收到的 FIX 管理消息
     195              :      * @param sessionID 消息来源的会话标识符
     196              :      *
     197              :      * 当收到会话层消息(Logon/Logout/Heartbeat/TestRequest)时调用。
     198              :      * 默认实现为空,子类可选择性重写用于日志记录等。
     199              :      *
     200              :      * @note 管理消息由 Session 自动处理,此回调仅用于通知
     201              :      */
     202            0 :     virtual void fromAdmin(const FixMessage& msg, const SessionID& sessionID) {
     203              :         (void)msg;
     204              :         (void)sessionID;
     205            0 :     }
     206              : 
     207              :     /**
     208              :      * @brief 发送管理消息前回调
     209              :      * @param msg 即将发送的 FIX 管理消息(可修改)
     210              :      * @param sessionID 发送消息的会话标识符
     211              :      *
     212              :      * 在发送 Logon/Logout/Heartbeat/TestRequest 前调用。
     213              :      * 默认实现为空,子类可选择性重写用于日志记录等。
     214              :      */
     215            0 :     virtual void toAdmin(FixMessage& msg, const SessionID& sessionID) {
     216              :         (void)msg;
     217              :         (void)sessionID;
     218            0 :     }
     219              : 
     220              :     // =========================================================================
     221              :     // 可选:持久化能力探测
     222              :     // =========================================================================
     223              : 
     224              :     /**
     225              :      * @brief 获取持久化存储接口(可选)
     226              :      *
     227              :      * 用于让网络层/会话层组件以“依赖倒置”的方式获取持久化能力:
     228              :      * - 当返回非空时,Session 可以将消息与会话序列号写入 store,用于断线恢复与 ResendRequest。
     229              :      * - 默认实现返回 nullptr,表示当前 Application 不提供持久化能力。
     230              :      *
     231              :      * @return IStore* 存储接口指针,可能为 nullptr
     232              :      */
     233            0 :     virtual IStore* getStore() const { return nullptr; }
     234              : };
     235              : 
     236              : } // namespace fix40
        

Generated by: LCOV version 2.0-1