Interaction between CPP and nodejs

1. Problem
first of all, the background is the interaction between CPP and js (addon), can be data, functions, and so on. Among them, js passes a json data to CPP, which is a CPPhttp network request, and then CPP opens up a child thread, establishes a tcp connection, then makes a http request, and finally passes the response information of the http request to the js layer, or callback nodejs to deal with the response information.

where CPP sets up tcp connections and http requests are implemented in one class, and the process is asynchronous, in which a callback function on_read () gets the response information from the server and processes it. After
CPP gets the json request from js, it starts to work on the network.

the problem is:
a. I don"t know when the response information will be returned, so I can"t wait for a response like Synchronize.
b. Api, of v8 cannot be used outside the main thread of js, that is, response information cannot be returned directly to js in the on_read () callback function

2. Code

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)

attempted method:
a. The while loop wait is set in the main thread, and the child thread sets a flag to indicate the end after on_read () returns data to js, which ends correctly, but the asynchronous request of the CPP becomes a Synchronize, which is meaningless.
b. The libuv method seen on the Internet, but there will still be the problem that the working function of libuv can not get the CPP asynchronous response message, which is mainly the problem of how to deal with the asynchronous message and CPP returning to node and how to deal with each other.

kneel down and beg the gods!

Apr.02,2021
Menu