首页 热点资讯 义务教育 高等教育 出国留学 考研考公
您的当前位置:首页正文

javascript-C++与nodejs的交互中出现的问题及实战代码

2020-11-27 来源:化拓教育网

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实战开发微博系统视频教程

显示全文