画布 1
终端互联网日志规范
  链路传播
    in
      browser
        二进制报文解析（业务端）
          对报文头进行处理，添加多几个字段
          终端框架修改，支持新旧数据传输
            如web端未传输新报文数据，则在内部自己生成对应的。
          需终端先上线
        json数据解析（用户桌面）
        全局变量变更/Event触发
          也需要传递对应的记录字段
      chromium
        json数据解析
          针对特性的几个字段进行解析，如果不存在，则自动生成对应的。
        全局变量变更/Event触发
    out
      分行服务
        序列化结构数据
          分行服务改造以适应对应的需求
          分行服务需支持新旧数据的传输
          分行服务需先上线
      硬件适配器模块、其他第三方库
        不跟踪到该第三方厂商库，在本地调用中根据返回值判定
    实体间传递
      实体外部接口
        正常调用，通过sp_rpc->sp_ses->CServerSessionBase异步运行
          框架默认创建thread Local变量，存储对应的调用链数据
        状态机跳转
          在另一个线程中，触发状态机状态变化
            PostEventFIFO
            PostEventLIFO
            FSM中添加链路信息，可通过类的全部变量获取
        通过Timer、Task、Thread的线程模型处理
          自己通过createThread方式启动的线程，实体自己处理
          通过Timer和Task创建的任务，提供重载的方式，能够放入对应的调用链
      广播消息
        OnLog
          重载OnLog，使用新的OnLog会添加对应的链路数据
            比较难以做对应的定制化，需实体自己处理
      全局变量
        OnSysVar
          重载OnSysVar，使用新的OnSysVar会添加对应的链路数据
            比较难以做对应的定制化，需实体自己处理
        GetVar
          完全不可感知
  日志上送
    日志存储
      db
        加密存储
          账号密码。。。
        保存容量上限
          200000
        不依赖于终端，所有实体、终端框架、外部厂商、都可以写入该数据库
        多进程调用
        涉及多个日志相关实体的改造
          upload，uplog，remotecontroller，,,,
    日志上送
      spshell读取db上传
        考虑从最新开始逐步上传
        日志上传限流
          最好是在服务器上实现，在终端上实现不可靠，没办法做到真正限流
  终端日志记录规范
    需整理实体的使用规范，已一个硬件实体作为对应的模板案例，最好有硬件适配器、分行服务外部系统、实体接口内部调用
  Enitity与web交互过程
    StartTcpBridgeServer
      sp_tbs_start
        server_proc
          bind
          listen
          MSG_STOP
            0
          MSG_UAC_ON_CONNECT
            1
          MSG_UAC_ON_DESTROY
            3
          MSG_UAC_ON_CLOSE
            2
          MSG_UAC_ON_ANS
            4
          MSG_ON_EVENT
            5
          相当于自己起了一个端口转发数据
          部分数据交互过程
    Chromium数据
      6F 00 00 00 01 00 00 00 04 00 00 0F xxxx
      len messagetype transId data
      messageType
        Info = 0, //info message, no response
        BeginSession = 1, //start entity session
        EndSession = 2, //end entity session
        Request = 3, //call request
        RequestAck = 4, //request acknowledge
        SessionAck = 5, //start session acknowledge
        Register = 6, //register entity event
        Unregister = 7, //unregister entity event
        Event = 8, //event message
        LogEventMsgType = 9, //log event
        LogWarnMsgType = 10, //log warn
    tcpBridge
      #define PKT_TYPE_INFO 0
      #define PKT_TYPE_SESSION 1
      #define PKT_TYPE_SESSIONEND 2
      #define PKT_TYPE_REQ 3
      #define PKT_TYPE_REQACK 4
      #define PKT_TYPE_SESSIONACK 5
      #define PKT_TYPE_REGISTER_EVENT 6
      #define PKT_TYPE_UNREGISTER_EVENT 7
      #define PKT_TYPE_EVENT_DATA 8
      #define PKT_TYPE_LOG_EVENT 9
      #define PKT_TYPE_LOG_WARN 10
      对应的MessageType, 4位int
        修改前16位为控制信息
        修改后16位为原数据信息
        sps
          #define SP_PKT_TSX 0x00000000 // for sp_tsx
          #define SP_PKT_RPC 0x10000000 // for sp_rpc
          #define SP_PKT_LOG 0x20000000 // for sp_log
          #define SP_PKT_VAR 0x30000000 // for sp_var
          #define SP_PKT_MOD 0x40000000 // for sp_mod
          #define SP_PKT_SES 0x50000000 // for sp_ses
          #define SP_PKT_BCM 0x60000000 // for sp_bcm
          多种数据类型
  代码相关
    重要结构
      struct bus_endpt_t {
int type;
int epid;
union {
HANDLE pipe_handle;
SOCKET sock_handle;
};
char *url;
bus_endpt_callback callback;
struct list_head msg_list;
spinlock_t msg_lock;
HANDLE msg_sem;
HANDLE tx_evt;
HANDLE rx_evt;
OVERLAPPED rx_overlapped;
int rx_pending;
int rx_pending_pkt_len;
iobuffer_queue_t *rx_buf_queue;
volatile int quit_flag;
};
      struct sock_connection {
SOCKET fd;
int idx;
int session_cnt;
struct hlist_head session_bucket[SESSION_BUCKET_SIZE];
int register_cnt;
struct hlist_head register_bucket[REGISTER_BUCKET_SIZE];
iobuffer_queue_t *tx_queue;
iobuffer_t *rx_pkt;
char rx_hdr_buf[RX_BUF_SIZE];
int rx_hdr_buf_len;
int rx_state;
int rx_header_len;
sp_tbs_t *tbs;
DECLARE_REF_COUNT_MEMBER(ref_cnt);
};
      struct sub_session {
struct hlist_node hentry;
unsigned int id;
unsigned int tsx_id;
sp_ses_uac_t *uac;
sock_connection *conn;
};
      typedef struct msg_t {
struct list_head entry;
int type;
int nparam;
int *params;
HANDLE evt;
int evt_result;
}msg_t;
        createEvent到evt中保证互斥，保证send
  arr_pkt_handler
    包处理函数，由key选择对应的数据处理
    Data
      key
      on_pkt
      user_data
    使用部分
      mod_on_pkt
      on_rx_pkt
        pkt_handler_list存储对不同类型的函数处理
        sp_svc_add_pkt_handler
          SP_PKT_BCM
          SP_PKT_LOG
          SP_PKT_MOD
          SP_PKT_RPC
          SP_PKT_SES
            mgr_on_pkt
              SES_CMD_INFO
                __threadpool_uas_process_info
                SpServerSessionFunction::on_info
          SP_PKT_VAR
    主调用部分
      bus_endpt_poll
        bus_endpt_recv_pkt
          endpt->callback.on_pkt
            sp_iom::on_pkt
  process_tcp_pkt
    on_info
      SP_PKT_SES|SES_CMD_INFO
    on_req
      SP_PKT_SES|SES_CMD_REQ
    on_session
      create_sub_session
        sp_ses_uac_create
        sp_ses_uac_async_connect
          sp_svc_send
            sp_iom_send
              bus_endpt_send_msg
      SP_PKT_SES|SES_CMD_CONN
    on_session_end
      SP_PKT_SES|SES_CMD_FINC
    on_register_event
      SP_PKT_BCM|BCM_CMD_SUBSCRIBE
    on_unregister_event
      SP_PKT_BCM|BCM_CMD_UNSUBSCRIBE
    on_log_event
      SP_PKT_LOG|LOG_CMD_RECORD
    on_log_warn
      SP_PKT_LOG|LOG_CMD_RECORD
    on_set_var_req
      SP_PKT_VAR|VAR_CMD_CHANGE
    on_get_var_req
      直接从共享内存里读
    收到数据，进行处理，大部分最终时通过sp_svc_send和sp_svc_post发出
  实体执行过程
    SpRun
      SpModule::Run()
        sp_iom_run(m_iom);
          bus_endpt_poll(iom->endpt, *timeout);
            bus_endpt_poll_internal(endpt, &result, timeout);
            endpt->callback.on_inf(endpt, epid, type, &pkt, endpt->callback.user_data);
              pkt_handler->on_pkt
                mod_on_pkt
                on_rx_pkt