libuv的典型應(yīng)用——CTP的Node.js封裝

寫過CTP的同學(xué)可能不多,這是一個期貨接口。沒聽說過的也無妨。

C++多線程回調(diào)

CTP 提供了若干個父類供開發(fā)者繼承,里面的回調(diào)都是通過覆蓋父類的純虛函數(shù)實(shí)現(xiàn)。
當(dāng)SDK有事件發(fā)生的時候,就會調(diào)用這些定義的回調(diào)函數(shù)。

class CThostFtdcTraderSpi
{
public:
    virtual void OnFrontConnected(){};
    virtual void OnFrontDisconnected(int nReason){};

編寫一個這樣的程序是十分痛苦的,因?yàn)榛卣{(diào)函數(shù)的執(zhí)行是在某個工作線程中。所以很容易引起并發(fā)讀寫的問題。代碼會變得十分復(fù)雜。

編寫過Node.js的同學(xué)一定以及十分習(xí)慣Node的單線程模式,回調(diào)函數(shù)執(zhí)行的時候雖然有點(diǎn)“不同步”,但好歹是在一個線程中,所以定義域里面的變量可以隨便使用。用慣這種方便的編程方式的同學(xué),如果去接觸一下C++那種多線程回調(diào),一定會抓狂的。

那么如何讓CTP開發(fā)也能很舒服呢?或者干脆將CTP封裝成Node的原生模塊,然后在Node中調(diào)用,豈不妙哉。

這時候協(xié)調(diào)C++多線程和Nodejs單線程的關(guān)鍵角色就登場了,這就是libuv。

#include <uv.h>
uv_async_t async_t;
uv_async_init(uv_default_loop(),&async_t,NULL);

我們可以初始化一個默認(rèn)的事件循環(huán)。
然后我們可以把所有的回調(diào)虛函數(shù)都用下面的方式去實(shí)現(xiàn)

void uv_trader::OnFrontConnected() {        
    CbRtnField* field = new CbRtnField();
    field->eFlag = T_ON_CONNECT;//FrontConnected
    field->work.data = field;
    uv_queue_work(uv_default_loop(), &field->work, _on_async, _on_completed);
}

其中_on_async是個空函數(shù),忽略。_on_completed函數(shù)回在事件循環(huán)的時候觸發(fā),保證在主線程中調(diào)用。然后我們在這個函數(shù)再去調(diào)用js的函數(shù)。

void uv_trader::_on_completed(uv_work_t * work,int){
    CbRtnField* cbTrnField = static_cast<CbRtnField*>(work->data);
    std::map<int, WrapTrader*>::iterator it = cb_map.find(cbTrnField->eFlag);
    if (it != cb_map.end()) {
        cb_map[cbTrnField->eFlag]->FunCallback(cbTrnField);
    }
    if (cbTrnField->rtnField)
        delete cbTrnField->rtnField;
    if (cbTrnField->rspInfo)
        delete cbTrnField->rspInfo;
    delete cbTrnField;
}

除了釋放資源,上面代碼就是從一個存儲著js回調(diào)函數(shù)的map中找到對應(yīng)的js函數(shù)進(jìn)行調(diào)用。

這些js函數(shù)都是在事先注冊好的,就在nodejs中。

trader.on("connect",function(result){
    console.log("on connected");
    trader.reqUserLogin('','','',function(result,iRequestID){
        console.log('login return val is '+result);
    });
});

js代碼寫起來就舒服多了。

https://github.com/langhuihui/node-ctp

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 很多Node.js初學(xué)者都會有這樣的疑惑,Node.js到底是單線程的還是多線程的?通過本章的學(xué)習(xí),能夠讓讀者較為...
    越努力越幸運(yùn)_952c閱讀 3,816評論 4 36
  • 總結(jié)一: [node.js總結(jié)](http://www.cnblogs.com/Darren_code/archi...
    xiumeiii閱讀 2,016評論 0 14
  • Node.js是目前非?;馃岬募夹g(shù),但是它的誕生經(jīng)歷卻很奇特。 眾所周知,在Netscape設(shè)計出JavaScri...
    w_zhuan閱讀 3,731評論 2 41
  • 1.ios高性能編程 (1).內(nèi)層 最小的內(nèi)層平均值和峰值(2).耗電量 高效的算法和數(shù)據(jù)結(jié)構(gòu)(3).初始化時...
    歐辰_OSR閱讀 30,224評論 8 265
  • 今天的二代軍??ㄩ_始出來了,默認(rèn)都是空卡,一般都是單位統(tǒng)一卡啟后才能辦,不支持個人辦理。 身份證生僻字,先做正常身...
    馮瑞_FR閱讀 419評論 0 0

友情鏈接更多精彩內(nèi)容