首頁  >  文章  >  web前端  >  javascript - C++與nodejs的互動中出現的問題及實戰程式碼

javascript - C++與nodejs的互動中出現的問題及實戰程式碼

php是最好的语言
php是最好的语言原創
2018-08-02 15:00:161524瀏覽

1. 問題

          首先,大背景是C 與js之間的交互作用(addon),可以是數據,函數等等。其中,js向C 傳遞一個json數據,這個數據是C http網路請求,然後C 開闢一個子線程,建立一個tcp連接,然後進行http請求,最後將http請求的回應訊息傳遞給js層,或是回呼nodejs處理響應訊息也可以。

其中,C 建立tcp連線和http請求是用一個類別實現的,過程都是異步的,其中有一個回呼函數on_read()會得到伺服器的回應訊息,並進行加工處理。
C 拿到js的json請求之後,便開始進行網路工作。

問題是:
a. 不知道回應訊息何時返回,無法像同步那樣等待回應。
b. 在js的主執行緒之外不能使用v8的api,也就是說無法在on_read()回呼函數中直接向js傳回回應訊息

2.程式碼

class TCP_CLIENT : public IConnectionHandler
{
    bool isdone;
public:
    TCP_CLIENT(const char* host, int port, const char* data, Isolate *isolate, const FunctionCallbackInfo<Value> args)
    {
        this->host_ = host;
        this->port_ = port;
        this->request_data_ = data;
        isolate_ = isolate;
    }
    ~TCP_CLIENT()
    {
        std::cout << "~tcp_client" << std::endl;
    }
    
    /*callback handler implement回调接口实现*/

    //建立连接的回调
    void on_established(IBaseConnection*  conn) override_final
    {
        std::cout << "Connect Successful" << std::endl;
        this->send_request(conn);
    }

    。。。。。。。。。
    
    //服务器响应得到数据的回调
    int on_read(int err, int bytes_transfered, IBaseConnection* conn, SharedBufferPtr buffer) override_final
    {

        if (err == 0 && bytes_transfered)
        {
            std::cout << "In read, thread id is ----" << GetCurrentThreadId() << std::endl;
            buffer->erase(bytes_transfered);
            if (conn->is_established())
            {
                conn->stop();
            }
                
        }
        return 0;
    }

    //发送数据的回调
    void on_write(int err, int bytes_transferred, IBaseConnection* conn, SharedBufferPtr buffer) override_final
    {
        if (err == 0 && bytes_transferred > 0)
        {
            std::cout << "Send Request Successful------>" << buffer->length() << std::endl;
            buffer->erase(bytes_transferred);
        }
        else {}
    }

private:
    const char* host_;
    int port_;
    const char* request_data_;
    http::ParserPtr response_parser_;
    Isolate *isolate_;
};


const char* ToCString(const v8::String::Utf8Value& value)
{
    return *value ? *value : "<string conversion failed>";
}

void entry(const FunctionCallbackInfo<Value>& args)
{
    std::cout << "In entry, process id is ----" << GetCurrentProcessId() << std::endl;
    std::cout << "In entry, thread id is ----" << GetCurrentThreadId() << std::endl;

    //启动一个线程执行tcp连接
    global_http_transfer_context_pool.run();

    Isolate* isolate = args.GetIsolate();

    if (args.Length() != 2)
    {
        isolate->ThrowException(Exception::TypeError(v8::String::NewFromUtf8(isolate, "参数数量必须为二")));
        return;
    }
    if (!args[0]->IsString() || !args[1]->IsNumber())
    {
        isolate->ThrowException(Exception::TypeError(
            v8::String::NewFromUtf8(isolate, "参数类型错误")
        ));
    }

    v8::String::Utf8Value str_temp(args[0]);
    const char* data = ToCString(str_temp);

    TCP_CLIENT* tcp_client;
    if (args[1]->NumberValue() == 1)
    {
        tcp_client = new TCP_CLIENT(cms_host, cms_port, data, isolate, args);
        tcp_client->perform(1);

    }
    else
    {
        tcp_client = new TCP_CLIENT(liteapp_host, liteapp_port, data, isolate, args);
        tcp_client->perform(0);
    }
}

void Init(Local<Object> exports)
{
    NODE_SET_METHOD(exports, "http_request", entry);
}

NODE_MODULE(NODE_GYP_MODULE_NAME, Init)

嘗試的方法:
a. 在主執行緒中設定while循環等待,子執行緒在on_read()向js傳回資料之後,設定標誌表示結束,這樣能夠正確結束,但是C 的非同步請求就變成了一個同步,沒有意義。
b. 在網路上看到的libuv方法,但是仍然會出現libuv的工作函數無法得到C 非同步回應訊息的問題,主要就是非同步訊息與C 向node返回,線程之間如何處理的問題。

相關文章:

NodeJS與Mysql的互動範例程式碼_javascript技巧

詳細介紹C#程式碼與javaScript函數的相互呼叫

相關影片:

Nodejs  mongoDB實戰開發微博系統影片教學

#

以上是javascript - C++與nodejs的互動中出現的問題及實戰程式碼的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn