Subscription.unsubscribe
退订:释放此订阅对象持有的引用;只有最后一个引用被释放时,才真正向交易所退订。
unsubscribe()示例
-
订阅ticker,收到10条后退订,改为订阅成交推送。
javascriptfunction main() { var tk = ctx.subscribe(exchange, {channel: "ticker"}) var n = 0 while (n < 10) { var ev = ctx.poll(tk, 1000) if (ev && ev.kind === 1) { Log("ticker", ev.last) n++ } } tk.unsubscribe() var trades = ctx.subscribe(exchange, {channel: "trade"}) while (true) { var t = ctx.poll(trades, 1000) if (t && t.kind === 4) { Log("trade", t.tradeId, t.side, t.px, t.qty) } } }pythondef main(): tk = ctx.subscribe(exchange, {"channel": "ticker"}) n = 0 while n < 10: ev = ctx.poll(tk, 1000) if ev is not None and ev.kind == 1: Log("ticker", ev.last) n += 1 tk.unsubscribe() trades = ctx.subscribe(exchange, {"channel": "trade"}) while True: t = ctx.poll(trades, 1000) if t is not None and t.kind == 4: Log("trade", t.tradeId, t.side, t.px, t.qty)rustfn main() { let tk = ctx::subscribe(exchange, ctx::SubOpts::ticker()).unwrap(); let mut n = 0; while n < 10 { match ctx::poll(&[tk.id()], Some(1000)) { ctx::Polled::Event(_) => n += 1, ctx::Polled::Stopped => return, _ => {} } } tk.unsubscribe().unwrap(); Log!("ticker unsubscribed after", n, "events"); } -
订阅归属于创建它的线程:在子线程中订阅相同内容会得到独立的事件流,且只能退订自己的订阅;主线程通过批量订阅返回的数组一次性退订两路订阅。
javascriptfunction main() { var subs = ctx.subscribe(0, {channel: "ticker", symbol: ["BTC_USDT", "ETH_USDT"]}) var t = threading.Thread(function() { // 线程里订阅同样的内容:得到自己的事件流,id与主线程的不同 var mine = ctx.subscribe(0, {channel: "ticker", symbol: "BTC_USDT"}) var id = mine.id mine.unsubscribe() // 自己的订阅可以退订 return id }) Log("main stream:", subs[0].id, "thread stream:", t.join().ret) subs.unsubscribe() // 主线程退订自己的两路 }pythonimport threading def main(): subs = ctx.subscribe(0, {"channel": "ticker", "symbol": ["BTC_USDT", "ETH_USDT"]}) def worker(): # 线程里订阅同样的内容:得到自己的事件流,id与主线程的不同 mine = ctx.subscribe(0, {"channel": "ticker", "symbol": "BTC_USDT"}) Log("main stream:", subs[0].id, "thread stream:", mine.id) mine.unsubscribe() # 自己的订阅可以退订 try: subs[0].unsubscribe() # 订阅属于主线程,这里会抛出异常 except Exception as e: Log("cannot unsubscribe here:", e) t = threading.Thread(target=worker) t.start() t.join() subs.unsubscribe() # 主线程退订自己的两路
参考
备注
在同一线程内,身份相同(账户、品种、频道、档数、周期均相同)的订阅共用一路事件流,每调用一次ctx.subscribe即增加一个引用。unsubscribe()只释放本对象持有的那一个引用,共用同一路事件流的其他订阅对象不受影响,仍正常接收事件;其他线程订阅的相同内容也各自持有引用。所有引用都释放后,托管者才向交易所退订,此后迟到的事件将被丢弃。
只有创建该订阅的线程才能退订:在其他线程中调用会抛出异常(错误信息包含belongs to another thread),订阅仍保持有效。线程结束时,其所有订阅会自动退订。
批量订阅返回的数组同样提供unsubscribe()方法,可一次性退订数组中的全部元素(每个元素各释放一个引用)。
对同一订阅对象重复调用unsubscribe()不会产生任何效果;订阅被交易所拒绝(收到prefillStatus为2的初始化状态事件)后再调用,同样不产生任何效果。退订后不能再调用该对象的book()、positions()、balances()方法。
退订后再次订阅相同内容,将获得新的事件流ID。
Python中为sub.unsubscribe(),批量订阅返回的SubscriptionList同样提供unsubscribe()。Rust中为sub.unsubscribe() -> Result<(), String>,在其他线程中调用会返回Err。ctx::Sub可以复制,引用数按ctx::subscribe()的调用次数计算:每调用一次ctx::subscribe(),对应调用一次unsubscribe();不要对复制出的同一句柄重复退订。