CEF 中从客户端到浏览器的消息传递序列化
Serialization for Messaging in CEF from Client to Browser
我有一个 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 协议缓冲区的序列化数据),哪种解决方案最好。据我所知,ArrayBuffer
在 CEF 中并没有得到真正的支持,这有点不幸。我们是否也可以滥用 CefString
或者这是一个坏主意?
这是完美手册https://bitbucket.org/chromiumembedded/cef/wiki/JavaScriptIntegration
扩展类似于 window 绑定,只是它们会加载到每一帧的上下文中,并且一旦加载就无法修改。加载扩展时 DOM 不存在,在扩展加载期间尝试访问 DOM 将导致崩溃。扩展使用 CefRegisterExtension() 函数注册,该函数应从 CefRenderProcessHandler::OnWebKitInitialized() 方法中调用。
JS 函数
CEF 支持使用本机实现创建 JS 函数。函数是使用接受名称和 CefV8Handler 参数的 CefV8Value::CreateFunction() 静态方法创建的。只能在上下文中创建和使用函数(有关详细信息,请参阅 "Working with Contexts" 部分)。
CefRefPtr<CefV8Handler> handler = …;
CefRefPtr<CefV8Value> func = CefV8Value::CreateFunction("myfunc", handler);
客户端应用程序必须提供的 CefV8Handler 接口的实现。
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);
};
函数和Window绑定
函数可用于创建复杂的 window 绑定。
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 function" 前向声明。
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,反之亦然。
我有一个 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 协议缓冲区的序列化数据),哪种解决方案最好。据我所知,ArrayBuffer
在 CEF 中并没有得到真正的支持,这有点不幸。我们是否也可以滥用 CefString
或者这是一个坏主意?
这是完美手册https://bitbucket.org/chromiumembedded/cef/wiki/JavaScriptIntegration
扩展类似于 window 绑定,只是它们会加载到每一帧的上下文中,并且一旦加载就无法修改。加载扩展时 DOM 不存在,在扩展加载期间尝试访问 DOM 将导致崩溃。扩展使用 CefRegisterExtension() 函数注册,该函数应从 CefRenderProcessHandler::OnWebKitInitialized() 方法中调用。
JS 函数
CEF 支持使用本机实现创建 JS 函数。函数是使用接受名称和 CefV8Handler 参数的 CefV8Value::CreateFunction() 静态方法创建的。只能在上下文中创建和使用函数(有关详细信息,请参阅 "Working with Contexts" 部分)。
CefRefPtr<CefV8Handler> handler = …;
CefRefPtr<CefV8Value> func = CefV8Value::CreateFunction("myfunc", handler);
客户端应用程序必须提供的 CefV8Handler 接口的实现。
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);
};
函数和Window绑定
函数可用于创建复杂的 window 绑定。
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 function" 前向声明。
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,反之亦然。