CTP: 为什么报网络原因发送失败,但连接却成功?

碰到一个很妖的问题,最后请教一位高手把问题定位到:

md is logining!
ptr :0x7f0318027d80
init ->
init <-
get api version :"v6.5.1_20200908 10:25:08"
get trade day :"20210222"
get_login_field -> 
login => 
req_user_login  return  => n :-1
行情登陆失败! => 网络原因发送失败
subsribe_marketdata=>
订阅标的 : ["IF2103", "au2103", "m2103"]
行情订阅失败: 网络原因发送失败!
join->
CtpMdSpi_Rust_OnFrontConnected ->
desk => on_front_connected
CtpMdSpi_Rust_OnFrontConnected <-
spi => 前置连接成功! MdSpiOnFrontConnected

从上面可以看到,spi收到回报,表明已经连接成功,但是在mdapi登陆时,却一直报错!这个感觉很奇怪。

问题出在 “刚刚注册完前置就登录,而是要等拿到连接回报再登录”

内在逻辑:
注册前置成功后,就会收到on_front_connected,如下:

CtpMdSpi_Rust_OnFrontConnected ->
desk => on_front_connected
CtpMdSpi_Rust_OnFrontConnected <-
spi => 前置连接成功! MdSpiOnFrontConnected

但如果login登录不成功,就可能会收到“网络原因发送失败”的消息。
注册前置(初始化)和登录是两个不同的异步事件。正常情况是注册前置(初始化)成功,再安排登录。

方案一:

1、在前置注册后,sleep 5秒,等待前置注册(初始化)完成。这个更简单,粗暴。【谨慎】
但是,5秒设置可能不合适,你可以打开快期的端口,也登陆一下,网络是否连接成功。不行试一下SIMNOW账户。

以下以Rust封装接口代码为例:

    println!("md is logining!");
    let flow_path = ::std::ffi::CString::new("").unwrap();
    let mut md_api = QuoteApi::new(flow_path, false, false);   
    md_api.register_spi(Box::new(my_desk));
    let front_add = std::ffi::CString::new(md_front).unwrap();     
    md_api.register_front(front_add);    
    md_api.init();
    let version = md_api.get_api_version();
    println!("get api version :{:?}",version);
    let trade_day = md_api.get_trade_day();
    println!("get trade day :{:?}",trade_day);
    std::thread::sleep(std::time::Duration::from_secs(5));// 注册前置成功后,再登陆 wait 5 second
    let mut login_field = get_login_field(&acc);
    let n_login = md_api.login(&mut login_field, 111_i32);

需要说明的是,这种sleep方式并不一定每次可能有效的。事实上是sleep阻塞几秒中,在赌注册前置(初始化)事件正好完成。

2、在spi回调返回连接成功后(on_front_connected),再登陆。这个更安全。[推荐]

你可能感兴趣的:(XTP,CTP,Rust,网络)