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 TestSchemeHandlerFactory::Create(
    CefRefPtr browser,
    CefRefPtr frame,
    const CefString& scheme_name,
    CefRefPtr 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 request,
        CefRefPtr callback);
    }
        
bool TestResourceHandler::ProcessRequest(CefRefPtr request,
    CefRefPtr callback) {

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

    CefRefPtr data = elements[0];
    int length = data->GetBytesCount();
    std::vector v;
    v.resize(length);
    data->GetBytes(length, &v[0]);
    //v里存储了arraybuffer的数据
    return true;
}

你可能感兴趣的:(cef中javascript和c++交换二进制数据(arraybuffer)的方法)