gpt4 book ai didi

javascript - CEF 中从客户端到浏览器的消息传递序列化

转载 作者:行者123 更新时间:2023-11-28 01:37:28 24 4
gpt4 key购买 nike

我有一个 Chromium 嵌入式框架 (CEF) 应用程序,我们希望在客户端 JavaScript 端与浏览器端之间进行通信。到目前为止,我们有可能使用通用消息路由器 GenericMessageRouter :客户端然后执行类似这样的操作来向浏览器线程发送消息:

var request_id = window.cefQuery({
request: 'my_request',
persistent: false,
onSuccess: function(response) {},
onFailure: function(error_code, error_message) {}
});

// which will be receiven by the browser with

bool OnQuery(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
int64 query_id,
const CefString& request,
bool persistent,
CefRefPtr<Callback> callback)

我想知道如果我们想要发送双向二进制数据(例如使用 Google Protocol Buffers 的序列化数据),哪种解决方案是最好的。据我所知,ArrayBuffer 在 CEF 中并没有得到真正的支持,这有点不幸。我们是否也可以滥用 CefString 或者这是一个坏主意?

最佳答案

这是完美的手册https://bitbucket.org/chromiumembedded/cef/wiki/JavaScriptIntegration

扩展类似于窗口绑定(bind),只是它们被加载到每一帧的上下文中,并且一旦加载就不能修改。加载扩展时 DOM 不存在,并且在扩展加载期间尝试访问 DOM 将导致崩溃。扩展使用 CefRegisterExtension() 函数注册,该函数应从 CefRenderProcessHandler::OnWebKitInitialized() 方法调用。

JS 函数

CEF 支持使用 native 实现创建 JS 函数。函数是使用 CefV8Value::CreateFunction() 静态方法创建的,该方法接受名称和 CefV8Handler 参数。只能在上下文中创建和使用函数(有关详细信息,请参阅“使用上下文”部分)。

CefRefPtr<CefV8Handler> handler = …;
CefRefPtr<CefV8Value> func = CefV8Value::CreateFunction("myfunc", handler);

必须由客户端应用程序提供的 CefV8Handler 接口(interface)的实现。

class MyV8Handler : public CefV8Handler {
public:
MyV8Handler() {}

virtual bool Execute(const CefString& name,
CefRefPtr<CefV8Value> object,
const CefV8ValueList& arguments,
CefRefPtr<CefV8Value>& retval,
CefString& exception) OVERRIDE {
if (name == "myfunc") {
// Extract argument values
// ...
// Do work
// ...
// Return my string value.
retval = CefV8Value::CreateString("My Value!");
return true;
}

// Function does not exist.
return false;
}

// Provide the reference counting implementation for this class.
IMPLEMENT_REFCOUNTING(MyV8Handler);
};

函数和窗口绑定(bind)

函数可用于创建复杂的窗口绑定(bind)。

void MyRenderProcessHandler::OnContextCreated(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefV8Context> context) {
// Retrieve the context's window object.
CefRefPtr<CefV8Value> object = context->GetGlobal();

// Create an instance of my CefV8Handler object.
CefRefPtr<CefV8Handler> handler = new MyV8Handler();

// Create the "myfunc" function.
CefRefPtr<CefV8Value> func = CefV8Value::CreateFunction("myfunc", handler);

// Add the "myfunc" function to the "window" object.
object->SetValue("myfunc", func, V8_PROPERTY_ATTRIBUTE_NONE);
}

在 JavaScript 中调用

<script language="JavaScript">
alert(window.myfunc(myJSON)); // Calls the function "myFunc" and passes the JSON through function argument
</script>

函数和扩展

函数可用于创建复杂的扩展。请注意使用扩展时需要的“ native 函数”前向声明。

void MyRenderProcessHandler::OnWebKitInitialized() {
// Define the extension contents.
std::string extensionCode =
"var test;"
"if (!test)"
" test = {};"
"(function() {"
" test.myfunc = function(json) {"
" native function myfunc();"
" return myfunc(json);"
" };"
"})();";

// Create an instance of my CefV8Handler object.
CefRefPtr<CefV8Handler> handler = new MyV8Handler();

// Register the extension.
CefRegisterExtension("v8/test", extensionCode, handler);
}

在 JavaScript 中调用

<script language="JavaScript">
alert(test.myfunc(myJSON)); // Calls the function "myFunc" and passes the JSON through function argument
</script>

Google protobuf 不适合 JS 和原生函数之间的互操作。使用 JSON。 JS 对象可以透明地序列化为 JSON,反之亦然。

关于javascript - CEF 中从客户端到浏览器的消息传递序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48665390/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com