cef中javascript和c++交换二进制数据(arraybuffer)的方法

javascript的arraybuffer如何传到c++?

javascript可以通过XMLHttpRequest的Get请求得到arraybuffer类型的数据,也可以通过POST请求,向服务器发送arraybuffer数据。
那么利用http请求和cef的custom scheme机制,javascript就可以与本地的c++代码交换arraybuffer数据。

注意:javascript运行在render进程,c++的custom scheme的处理器在browser进程。

基础知识

scheme就是一种协议,比如http://helloworld.com中的http就是scheme,不过它是内置的。
zhangpeng://helloworld.com中的zhangpeng就是一个自定义scheme。
当cef中通过XMLHttpRequest请求地址zhangpeng://helloworld.com时,我们c++中实现的处理器,就会收到这个请求。
但是XMLHttpRequest只支持http/https两种内置的scheme。
所以我们只能定义http、https的自定义scheme handler。
##使用http scheme交换arraybuffer

一、cef注册custom scheme 来接收http请求

在cef中我们可以通过以下接口来注册scheme

CefRegisterSchemeHandlerFactory();

注册一个自定义http scheme

CefRegisterSchemeHandlerFactory("http", "zhangpeng", new TestSchemeHandlerFactory());

这个scheme限定了,scheme为"http",domain为"zhangpeng",只有当请求为"http://zhangpeng/"开头时,才会执行自定义c++代码。
处理器工厂为TestSchemeHandlerFactory,是我们自己实现的处理请求的c++代码。

当收到请求时,cef会调用TestSchemeHandlerFactory的Create方法,该方法返回一个TestResourceHandler

CefRefPtr<CefResourceHandler> TestSchemeHandlerFactory::Create(
	CefRefPtr<CefBrowser> browser,
	CefRefPtr<CefFrame> frame,
	const CefString& scheme_name,
	CefRefPtr<CefRequest> request) {
	return new TestResourceHandler();
}

当javascript通过XMLHttpRequest请求地址:http://zhangpeng/ 地址时,我们的c++代码将收到这个请求。

二、使用javascript发送arraybuffer

javascript代码如下:

//假设data是你需要发送的arraybuffer
var url = 'http://zhangpeng/';
var int8View = new window.Uint8Array(data);
var xhr = new XMLHttpRequest();
xhr.open('POST', url, true);
xhr.send(int8View);

三、c++收到arraybuffer数据

C++我们会收到请求,我们可以拿到arraybuffer,这里是browser进程

class TestResourceHandler : public CefResourceHandler {
public:
	virtual bool ProcessRequest(CefRefPtr<CefRequest> request,
		CefRefPtr<CefCallback> callback);
    }
		
bool TestResourceHandler::ProcessRequest(CefRefPtr<CefRequest> request,
	CefRefPtr<CefCallback> callback) {

	CefRefPtr<CefPostData> data_array = request->GetPostData();
	if (data_array->GetElementCount() == 0) {
		return false;
	}
	CefPostData::ElementVector elements;
	data_array->GetElements(elements);

	CefRefPtr<CefPostDataElement> data = elements[0];
	int length = data->GetBytesCount();
	std::vector<uint8_t> v;
	v.resize(length);
	data->GetBytes(length, &v[0]);
	//v里存储了arraybuffer的数据
	return true;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章