Maison  >  Article  >  interface Web  >  javascript - Problèmes et codes pratiques dans l'interaction entre C++ et Nodejs

javascript - Problèmes et codes pratiques dans l'interaction entre C++ et Nodejs

php是最好的语言
php是最好的语言original
2018-08-02 15:00:161534parcourir

1. Question

Tout d'abord, le grand contexte est l'interaction (addon) entre C++ et js, qui peut être des données, fonctions, etc. Parmi eux, js transfère une donnée json vers C++. Ces données sont une requête réseau http C++. Ensuite, C++ ouvre un sous-thread, établit une connexion TCP, puis effectue une requête http et transmet enfin les informations de réponse de la requête http. la couche js, ou Il est également possible de rappeler nodejs pour traiter les informations de réponse.

Parmi eux, C++ établit une connexion TCP et une requête http à l'aide d'une classe, et le processus est asynchrone. Il existe une fonction de rappel on_read() qui obtiendra les informations de réponse du serveur et les traitera.
Une fois que C++ a reçu la requête json de js, il démarre le travail réseau.

Le problème est :
a. Je ne sais pas quand les informations de réponse seront renvoyées et j'ai hâte de recevoir la réponse, comme la synchronisation.
b. L'API v8 ne peut pas être utilisée en dehors du thread principal de js, ce qui signifie que les informations de réponse ne peuvent pas être directement renvoyées à js dans la fonction de rappel on_read()

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)

Méthodes à essayer :
a. Configurez une boucle while pour attendre dans le thread principal après que le sous-thread ait renvoyé les données à js dans on_read(. ), définissez un indicateur pour indiquer la fin. Cela peut se terminer correctement, mais la requête asynchrone C++ devient une synchronisation, ce qui n'a aucun sens.
b. J'ai vu la méthode libuv sur Internet, mais il y a toujours un problème : la fonction de travail libuv ne peut pas obtenir le message de réponse asynchrone C++. Le problème principal est de savoir comment gérer le message asynchrone et le retour C++ au nœud. et comment le gérer entre les threads.

Articles connexes :

Exemples de compétences code_javascript d'interaction NodeJS et Mysql

Introduction détaillée au code C# et aux fonctions javaScript Appels mutuels

Vidéos associées :

Tutoriel vidéo sur le développement pratique du système Weibo de Nodejs + mongoDB

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn