public abstract class CefMessageRouter
extends java.lang.Object
The below classes implement support for routing aynchronous messages between
JavaScript running in the renderer process and C++ running in the browser
process. An application interacts with the router by passing it data from
standard CEF C++ callbacks (OnBeforeBrowse, OnProcessMessageRecieved,
OnContextCreated, etc). The renderer-side router supports generic JavaScript
callback registration and execution while the browser-side router supports
application-specific logic via one or more application-provided Handler
instances.
The renderer-side router implementation exposes a query function and a cancel
function via the JavaScript 'window' object:
// Create and send a new query.
var request_id = window.cefQuery({
request: 'my_request',
persistent: false,
onSuccess: function(response) {},
onFailure: function(error_code, error_message) {}
});
// Optionally cancel the query.
window.cefQueryCancel(request_id);
When |window.cefQuery| is executed the request is sent asynchronously to one
or more C++ Handler objects registered in the browser process. Each C++
Handler can choose to either handle or ignore the query in the
Handler::OnQuery callback. If a Handler chooses to handle the query then it
should execute Callback::Success when a response is available or
Callback::Failure if an error occurs. This will result in asynchronous
execution of the associated JavaScript callback in the renderer process. Any
queries unhandled by C++ code in the browser process will be automatically
canceled and the associated JavaScript onFailure callback will be executed
with an error code of -1.
Queries can be either persistent or non-persistent. If the query is
persistent than the callbacks will remain registered until one of the
following conditions are met:
A. The query is canceled in JavaScript using the |window.cefQueryCancel|
function.
B. The query is canceled in C++ code using the Callback::Failure function.
C. The context associated with the query is released due to browser
destruction, navigation or renderer process termination.
If the query is non-persistent then the registration will be removed after
the JavaScript callback is executed a single time. If a query is canceled for
a reason other than Callback::Failure being executed then the associated
Handler's OnQueryCanceled method will be called.
Some possible usage patterns include:
One-time Request. Use a non-persistent query to send a JavaScript request.
The Handler evaluates the request and returns the response. The query is
then discarded.
Broadcast. Use a persistent query to register as a JavaScript broadcast
receiver. The Handler keeps track of all registered Callbacks and executes
them sequentially to deliver the broadcast message.
Subscription. Use a persistent query to register as a JavaScript subscription
receiver. The Handler initiates the subscription feed on the first request
and delivers responses to all registered subscribers as they become
available. The Handler cancels the subscription feed when there are no
longer any registered JavaScript receivers.
Message routing occurs on a per-browser and per-context basis. Consequently,
additional application logic can be applied by restricting which browser or
context instances are passed into the router. If you choose to use this
approach do so cautiously. In order for the router to function correctly any
browser or context instance passed into a single router callback must then
be passed into all router callbacks.
There is generally no need to have multiple renderer-side routers unless you
wish to have multiple bindings with different JavaScript function names. It
can be useful to have multiple browser-side routers with different client-
provided Handler instances when implementing different behaviors on a per-
browser basis.
This implementation places no formatting restrictions on payload content.
An application may choose to exchange anything from simple formatted
strings to serialized XML or JSON data.
EXAMPLE USAGE
1. Define the router configuration. You can optionally specify settings
like the JavaScript function names. The configuration must be the same in
both the browser and renderer processes. If using multiple routers in the
same application make sure to specify unique function names for each
router configuration.
// Example config object showing the default values.
CefMessageRouterConfig config = new CefMessageRouterConfig();
config.jsQueryFunction = "cefQuery";
config.jsCancelFunction = "cefQueryCancel";
2. Create an instance of CefMessageRouter in the browser process.
messageRouter_ = CefMessageRouter.create(config);
3. Register one or more Handlers. The Handler instances must either outlive
the router or be removed from the router before they're deleted.
messageRouter_.addHandler(myHandler);
4. Add your message router to all CefClient instances you want to get your
JavaScript code be handled.
myClient.addMessageRouter(messageRouter_);
4. Execute the query function from JavaScript code.
window.cefQuery({request: 'my_request',
persistent: false,
onSuccess: function(response) { print(response); },
onFailure: function(error_code, error_message) {} });
5. Handle the query in your CefMessageRouterHandler.onQuery implementation
and execute the appropriate callback either immediately or asynchronously.
public boolean onQuery(CefBrowser browser,
long query_id,
String request,
boolean persistent,
CefQueryCallback callback) {
if (request.indexOf("my_request") == 0) {
callback.success("my_response");
return true;
}
return false; // Not handled.
}
6. Notice that the success callback is executed in JavaScript.
(下面的类实现了对在渲染器进程中运行的JavaScript和在浏览器进程中运行的C ++之间路由异步消息的支持。应用程序通过从标准CEF C ++回调(OnBeforeBrowse,OnProcessMessageRecieved,OnContextCreated等)传递数据来与路由器交互。渲染器端路由器支持通用JavaScript回调注册和执行,而浏览器端路由器通过一个或多个应用程序提供的Handler实例支持特定于应用程序的逻辑。渲染器端路由器实现通过JavaScript“窗口”对象公开查询函数和取消函数://创建并发送新查询。 var request_id = window.cefQuery({request:'my_request',persistent:false,onSuccess:function(response){},onFailure:function(error_code,error_message){}}); //(可选)取消查询。 window.cefQueryCancel(REQUEST_ID);当| window.cefQuery |执行时,请求将异步发送到浏览器进程中注册的一个或多个C ++ Handler对象。每个C ++处理程序都可以选择在Handler :: OnQuery回调中处理或忽略查询。如果处理程序选择处理查询,那么它应该在响应可用时执行Callback :: Success,或者如果发生错误则执行Callback :: Failure。这将导致在渲染器进程中异步执行关联的JavaScript回调。浏览器进程中未被C ++代码处理的任何查询将被自动取消,并且将执行关联的JavaScript onFailure回调,错误代码为-1。查询可以是持久查询,也可以是非持久查询。如果查询是持久的,则回调将保持注册,直到满足下列条件之一:A。使用| window.cefQueryCancel |在JavaScript中取消查询。功能。 B.使用Callback :: Failure函数在C ++代码中取消查询。 C.由于浏览器破坏,导航或渲染器进程终止,释放与查询相关联的上下文。如果查询是非持久性的,那么在一次执行JavaScript回调之后将删除注册。如果由于Callback :: Failure正在执行以外的原因而取消查询,则将调用关联的Handler的OnQueryCanceled方法。一些可能的使用模式包括:一次性请求。使用非持久性查询发送JavaScript请求。 Handler评估请求并返回响应。然后丢弃该查询。广播。使用持久性查询注册为JavaScript广播接收器。处理程序跟踪所有已注册的回调并按顺序执行它们以传送广播消息。订阅。使用持久性查询注册为JavaScript订阅接收者。处理程序在第一个请求时启动订阅源,并在所有已注册的订户可用时向其发送响应。当不再有任何已注册的JavaScript接收器时,处理程序取消订阅源。消息路由基于每个浏览器和每个上下文进行。因此,可以通过限制将哪个浏览器或上下文实例传递到路由器来应用其他应用程序逻辑。如果您选择使用此方法,请谨慎使用。为了使路由器正常运行,必须将传递到单个路由器回调的任何浏览器或上下文实例传递到所有路由器回调中。除非您希望具有不同JavaScript函数名称的多个绑定,否则通常不需要具有多个渲染器端路由器。在基于每个浏览器的基础上实现不同的行为时,让多个浏览器端路由器具有不同的客户端提供的Handler实例会很有用。此实现不对有效内容进行格式限制。应用程序可以选择交换从简单格式化字符串到序列化XML或JSON数据的任何内容。示例用法1.定义路由器配置。您可以选择指定JavaScript函数名称等设置。浏览器和渲染器进程中的配置必须相同。如果在同一应用程序中使用多个路由器,请确保为每个路由器配置指定唯一的功能名称。 //示例配置对象显示默认值。 CefMessageRouterConfig config = new CefMessageRouterConfig(); config.jsQueryFunction =“cefQuery”; config.jsCancelFunction =“cefQueryCancel”; 2.在浏览器进程中创建CefMessageRouter实例。 messageRouter_ = CefMessageRouter.create(config); 3.注册一个或多个处理程序。 Handler实例必须要么比路由器更长,要么在删除之前从路由器中删除。 messageRouter_.addHandler(将myHandler); 4.将消息路由器添加到要处理JavaScript代码的所有CefClient实例。 myClient.addMessageRouter(messageRouter_); 4.从JavaScript代码执行查询功能。 window.cefQuery({request:'my_request',persistent:false,onSuccess:function(response){print(response);},onFailure:function(error_code,error_message){}}); 5.在CefMessageRouterHandler.onQuery实现中处理查询,并立即或异步执行适当的回调。 public boolean onQuery(CefBrowser browser,long query_id,String request,boolean persistent,CefQueryCallback callback){if(request.indexOf(“my_request”)== 0){callback.success(“my_response”); 返回true; } return false; //没处理 注意,成功回调是在JavaScript中执行的)