接着http://chromium.world/?id=1的“N. 后续逻辑”来。本文由@leonwxqian (各社交媒体同号)编写。
Mojo消息接受者注册时使用Dispatcher模式。
客户端向中间人注册一个回调(Event handler)
中间人检测到就绪状态,产生事件调用所有相关的回调
调用具体的工作类
中间人是一个不断循环的单独线程,它接受所有 handler 的注册,并负责查询状态,就绪后用指定的handler进行处理。类似于邮件的投递过程。
以BlobRegistry为例。在RenderProcessHostImpl::RegisterMojoInterfaces处,
registry->AddInterface( base::BindRepeating(&BlobRegistryWrapper::Bind, storage_partition_impl_->GetBlobRegistry(), GetID()));
代码向service_manager::BinderRegistry*,registry注册了接口,绑定了BlobRegistryWrapper::Bind,this为storage_partition_impl_->GetBlobRegistry()即BlobRegistry*。
“中间人”即:service_manager::BinderRegistry。
std::unique_ptr<storage::BlobRegistryImpl> blob_registry_; void BlobRegistryWrapper::Bind(int process_id, blink::mojom::BlobRegistryRequest request) { DCHECK_CURRENTLY_ON(BrowserThread::IO); blob_registry_->Bind(std::move(request), std::make_unique<BindingDelegate>(process_id)); }
其绑定的BlobRegistryRequest是mojo::InterfaceRequest<BlobRegistry>的语法糖。InterfaceRequest表示来自远程客户端的通过指定消息管道实现接口的请求。
回到Mojo消息的接受者处。mojo::InterfaceEndpointClient::HandleValidatedMessage的实现为MessageReceiver*,incoming_receiver_->AcceptWithResponder。
BlobRegistryStub继承于mojo::MessageReceiverWithResponderStatus。因此,在 InterfacePtrState<T>::AcceptWithResponder --> InterfacePtrState<T>::ForwardMessageWithResponder进行消息转发后,由BlobRegistryStub首先收到消息。
收到消息后,经过如下路径传递:BlobRegistryStub::AcceptWithResponder --> BlobRegistryStubDispatch::AcceptWithResponder
根据收到的不同消息类型(message->header()->name),BlobRegistryStubDispatch::AcceptWithResponder 会调用不同函数。
internal::kBlobRegistry_Register_Name | impl->Register |
internal::kBlobRegistry_RegisterFromStream_Name | impl->RegisterFromStream |
internal::kBlobRegistry_GetBlobFromUUID_Name | impl->GetBlobFromUUID |
internal::kBlobRegistry_URLStoreForOrigin_Name | NOT REACHED |
impl为storage::BlobRegistryImpl*即impl->Register为:storage::BlobRegistryImpl::Register。
至此,程序正式地通过mojo调用到了客户端逻辑。
附:
MakeRequest会接受管道的一个handle,并创建一个InterfaceRequest<T>。
template <typename Interface> InterfaceRequest<Interface> MakeRequest( InterfacePtr<Interface>* ptr, scoped_refptr<base::SequencedTaskRunner> runner = nullptr) { MessagePipe pipe; ptr->Bind(InterfacePtrInfo<Interface>(std::move(pipe.handle0), 0u), std::move(runner)); return InterfaceRequest<Interface>(std::move(pipe.handle1)); } // 类似上面的,只是绑定消息管道的一端到一个InterfacePtrInfo实例上。 template <typename Interface> InterfaceRequest<Interface> MakeRequest(InterfacePtrInfo<Interface>* ptr_info) { MessagePipe pipe; ptr_info->set_handle(std::move(pipe.handle0)); ptr_info->set_version(0u); return InterfaceRequest<Interface>(std::move(pipe.handle1)); }
----------------------------------------------------------------------------------------------------------------------
示例1:请求接口的远程实现。
给定以下接口:
interface Database { OpenTable(Table& table); }
客户端的代码类似于以下代码:
DatabasePtr database = ...; // Connect to database. TablePtr table; database->OpenTable(MakeRequest(&table));
从MakeRequest返回后,|table|已准备好对其调用方法。
示例2:向远程服务注册本地实现。
给定以下接口。
Given the following interface interface Collector { RegisterSource(Source source); }
客户端的代码类似于以下代码:
CollectorPtr collector = ...; // Connect to Collector. SourcePtr source; InterfaceRequest<Source> source_request(&source); collector->RegisterSource(std::move(source)); CreateSource(std::move(source_request)); // 在本地创建实现。