Chromium Mojo消息管道的创建和使用文档

Chromium Mojo 消息管道的创建和使用

版本备注编写人时间
V1.0初稿wangnn012020-1-9

一、Mojo 消息管道(无响应)

S1 render 端

1.定义接口

​ 在src/services/spider_mojo/ mojom/spider_mojo.mojom中创建以下Mojom文件,来定义一个简单的Logger接口,客户端可以使用该接口来输出简单的字符串消息:

1.	module spider_mojo.mojom;  
2.	  
3.	interface Logger{  
4.	    Log(string message);  
5.	};  

还有一个GN目标(src/services/spider_mojo/ mojom/BUILD.gn)用来生成绑定:

1.	import("//mojo/public/tools/bindings/mojom.gni")  
2.	mojom("mojom") {  
3.	  sources = [ "spider_mojo.mojom" ]  
4.	}  

确保需要此接口的任何目标都依赖于此接口,例如,在对应模块的BUILD.gn中添加像这样的一行:

1.	deps += [ '//services/spider_mojo/mojom' ]  

​ 例如,在本示例中,render和browser进程中都需要Logger接口,因此需要在两个进程各自对应的模块中添加依赖,后面会详细讲述。

注:*.mojom

​ .mojom 是 mojo 的模板文件, mojo 类似于 Android 的 AIDL ,提供了跨语言(C++ / Java / JavaScript)的进程间对象(Object)通信机制, mojom 文件也类似于 aidl 文件,会生成进程间通信对象的抽象接口以及其底层的 IPC 实现。

2.创建管道&发送消息&发送一个PendingReceiver 至Browser

​ 本示例中,我们在src/third_party/blink/renderer/core/html/parser/html_construction_site.cc的函数HTMLConstructionSite::FinishedParsing中添加如下代码:

1.	//创建消息管道
2.	mojo::Remote<spider_mojo::mojom::Logger> remote;  
3.	mojo::PendingReceiver<spider_mojo::mojom::Logger> receiver = remote.BindNewPipeAndPassReceiver();  
4.	//发送消息
5.	remote->Log("Hello");  
6.	//发送一个PendingReceiver到Browser
7.	document_->GetBrowserInterfaceBroker().GetInterface(std::move(receiver));  

​ 注意:为了使用mojo相关的方法,还需在src/third_party/blink/renderer/core/html/parser/html_construction_site.cc中添加相应头文件:

1.	#include "services/spider_mojo/mojom/spider_mojo.mojom.h"  
2.	//spider_mojo_impl.h为接口Logger的实现,在browser进程中定义,后续会详细讲述
3.	#include "content/browser/spider_mojo/spider_mojo_impl.h"  

​ 在src/third_party/blink/renderer/core/html/parser/BUILD.gn中添加对接口Logger的依赖:

deps+={
    "//services/spider_mojo/mojom"
}

​ render端的操作已完成,接下来是browser端。

S2 browser端

1.实现接口

​ 本示例中,在src/content/browser中新建文件夹“spider_mojo”,并在该文件夹中新建spider_mojo_impl.h和spider_mojo_impl.cc。

​ 其中,spider_mojo_impl.h的内容:

1.	#include "base/logging.h"  
2.	#include "base/macros.h"  
3.	#include "mojo/public/cpp/bindings/receiver.h"  
4.	#include "mojo/public/cpp/bindings/binding.h"  
5.	#include "mojo/public/cpp/bindings/interface_request.h"  
6.	#include "services/spider_mojo/mojom/spider_mojo.mojom.h"  
7.	  
8.	namespace content{  
9.	class LoggerImpl : public spider_mojo::mojom::Logger {  
10.	 public:  
11.	  // NOTE: A common pattern for interface implementations which have one  
12.	  // instance per client is to take a PendingReceiver in the constructor.  
13.	  
14.	  explicit LoggerImpl(mojo::PendingReceiver<spider_mojo::mojom::Logger> receiver);  
15.	   
16.	  ~LoggerImpl() override;  
17.	  
18.	  // spider_mojo::mojom::Logger:  
19.	  void Log(const std::string& message) override;  
20.	  
21.	 private:  
22.	  mojo::Receiver<spider_mojo::mojom::Logger> receiver_;  
23.	  
24.	  DISALLOW_COPY_AND_ASSIGN(LoggerImpl);  
25.	};  
26.	} //namespace content  

​ spider_mojo_impl.cc的内容:

1.	#include "content/browser/spider_mojo/spider_mojo_impl.h"  
2.	#include <utility>  
3.	#include "base/bind.h"  
4.	  
5.	namespace content{  
6.	LoggerImpl::LoggerImpl(mojo::PendingReceiver<spider_mojo::mojom::Logger> receiver)  
7.	    : receiver_(this, std::move(receiver)) {}  
8.	  
9.	LoggerImpl::~LoggerImpl(){}  
10.	  
11.	void LoggerImpl::Log(const std::string& message) {  
12.	  LOG(INFO) << "[Logger] " << message;  
13.	}  
14.	} // namespace content  

​ 在src/content/browser/BUILD.gn中相应位置添加依赖deps以及source:

1.	deps += [  
2.	"//services/spider_mojo/mojom",  
3.	]  
...
1.	sources += [  
2.	    "spider_mojo/spider_mojo_impl.h",  
3.	    "spider_mojo/spider_mojo_impl.cc",  
4.	]  

2.注册接口

注:*号为前缀的代码行需新添加。

1.	//src/content/browser/frame_host/render_frame_host_impl.h
2.	...  
3.	*#include "services/spider_mojo/mojom/spider_mojo.mojom.h"
4.	*#include "content/browser/spider_mojo/spider_mojo_impl.h"  
5.	...  
6.	  
7.	namespace content {  
8.	...  
9.	*class LoggerImpl;  
10.	...  
11.	class CONTENT_EXPORT RenderFrameHostImpl{  
12.	public:  
13.	...  
14.	*void GetLogger(mojo::PendingReceiver<spider_mojo::mojom::Logger> receiver);  
15.	...  
16.	private:  
17.	...  
18.	*std::unique_ptr<LoggerImpl> logger_;  
19.	...  
20.	};  

1.	//src/content/browser/frame_host/render_frame_host_impl.cc  
2.	...  
3.	* void RenderFrameHostImpl::GetLogger(mojo::PendingReceiver<spider_mojo::mojom::Logger> receiver){  
4.	      * logger_ = std::make_unique<LoggerImpl>(std::move(receiver));  
5.	      * LOG(INFO) << "Launching Successfully";  
6.      *}
1.	//src/content/browser/browser_interface_binders.cc  
2.	...  
3.	* #include "services/spider_mojo/mojom/spider_mojo.mojom.h"  
4.	...  
5.	// Documents/frames  
6.	void PopulateFrameBinders(RenderFrameHostImpl* host,  
7.	                          service_manager::BinderMap* map) {  
8.	...  
9.	* map->Add<spider_mojo::mojom::Logger>(base::BindRepeating(  
10.	      &RenderFrameHostImpl::GetLogger,base::Unretained(host)));  
11.	...  
12.	}  

S3 编译

1.编译生成接口对应的源文件

​ 使用ninja编译目标:

1.	//在src/out/default目录下执行  
2.	ninja services/spider_mojo/mojom 

​ 执行完毕后,将会在src/out/Defaul/gen/service中生成相应的文件夹“spider_mojo”,该文件夹中包含生成的一些源文件:

2.编译content模块

​ 使用ninja编译:

1.	// 在src/out//Default目录下执行  
2.	ninja content  

​ 至此,大功告成,编译后会Log输出“hello”。

二、Mojo 消息管道(带响应)

​ 创建过程和无响应的Mojo消息管道类似。

S1 render 端

1.定义接口

​ 在src/services/spider_mojo/ mojom/spider_mojo.mojom中创建以下Mojom文件,来定义一个简单的Logger接口,客户端可以使用该接口来输出简单的字符串消息:

module blink.mojom;

interface Logger{
    Log(string message);  
    GetTail() => (string message);  
}; 

​ 还有一个GN目标(src/services/spider_trans/ mojom/BUILD.gn)用来生成绑定:

import("//mojo/public/tools/bindings/mojom.gni")
mojom("mojom") {
  sources = [ "spider_mojo.mojom" ]
} 

​ 确保需要此接口的任何目标都依赖于此接口,例如,在对应模块的BUILD.gn中添加像这样的一行:

1.	deps += [ '//services/spider_mojo/mojom' ]  

​ 例如,在本示例中,render和browser进程中都需要Logger接口,因此需要在两个进程各自对应的模块中添加依赖,后面会详细讲述。

注:*.mojom

​ .mojom 是 mojo 的模板文件, mojo 类似于 Android 的 AIDL ,提供了跨语言(C++ / Java / JavaScript)的进程间对象(Object)通信机制, mojom 文件也类似于 aidl 文件,会生成进程间通信对象的抽象接口以及其底层的 IPC 实现。

2.创建管道&发送消息&发送一个PendingReceiver 至Browser

​ 本示例中,我们在src/third_party/blink/renderer/core/html/parser/html_construction_site.cc中添加如下代码:

void HTMLConstructionSite::OnGetTail(const std::string& message) {  
	LOG(ERROR) << "Tail was: " << message;  
}  
...
void HTMLConstructionSite::FinishedParsing(){
    ...
    //创建消息管道
    mojo::Remote<spider_mojo::mojom::Logger> remote; 
    mojo::PendingReceiver<spider_mojo::mojom::Logger> receiver = remote.BindNewPipeAndPassReceiver();   
    //发送一个PendingReceiver到Browser
    document_->GetBrowserInterfaceBroker().GetInterface(std::move(receiver));  
    //发送消息
    remote->Log("Hello"); 
    //获得响应
    remote->GetTail(base::BindOnce(&OnGetTail) ,base::Unretained(this));  
    ...  
}

​ 注意:为了使用mojo相关的方法,还需在src/third_party/blink/renderer/core/html/parser/html_construction_site.cc中添加相应头文件:

1.	#include "services/spider_mojo/mojom/spider_mojo.mojom.h"  
2.	//spider_mojo_impl.h为接口Logger的实现,在browser进程中定义,后续会详细讲述
3.	#include "content/browser/spider_mojo/spider_mojo_impl.h"  

​ 在src/third_party/blink/renderer/core/html/parser/BUILD.gn中添加对接口Logger的依赖:

deps+={
    "//services/spider_mojo/mojom"
}

​ render端的操作已完成,接下来是browser端。

S2 browser端

1.实现接口

本示例中,在src/content/browser中新建文件夹“spider_mojo”,并在该文件夹中新建spider_mojo_impl.h和spider_mojo_impl.cc。

​ 其中,spider_mojo_impl.h的内容:

#include "base/logging.h"  
#include "base/macros.h"  
#include "mojo/public/cpp/bindings/receiver.h"  
#include "mojo/public/cpp/bindings/binding.h"  
#include "mojo/public/cpp/bindings/interface_request.h"  
#include "services/spider_mojo/mojom/spider_mojo.mojom.h" 	
namespace content{  
	class LoggerImpl : public spider_mojo::mojom::Logger {  
	 public:  
	  // NOTE: A common pattern for interface implementations which have one  
	  // instance per client is to take a PendingReceiver in the constructor.  
	  explicit LoggerImpl(mojo::PendingReceiver<spider_mojo::mojom::Logger> receiver); 	 	   ~LoggerImpl() override;  
      // spider_mojo::mojom::Logger:  
      void Log(const std::string& message) override;  
      void GetTail(GetTailCallback callback) override;
	 private:  
	  mojo::Receiver<spider_mojo::mojom::Logger> receiver_;  
      std::string response;
	  DISALLOW_COPY_AND_ASSIGN(LoggerImpl);  
	};  
} //namespace content      

​ spider_mojo_impl.cc的内容:

#include "content/browser/spider_mojo/spider_mojo_impl.h"  
#include <utility>  
#include "base/bind.h"  

namespace content{  
    LoggerImpl::LoggerImpl(mojo::PendingReceiver<spider_mojo::mojom::Logger> receiver)  
        : receiver_(this, std::move(receiver)) {}  

    LoggerImpl::~LoggerImpl(){}  

    void LoggerImpl::Log(const std::string& message) {  
      LOG(INFO) << "[Logger] " << message;  
      response = message;
    }  
    
    void GetTail(GetTailCallback callback) {  
	  std::move(callback).Run(response);  
	}  

} // namespace content  

​ 在src/content/browser/BUILD.gn中相应位置添加依赖deps以及source:

1.	deps += [  
2.	"//services/spider_mojo/mojom",  
3.	]  
...
1.	sources += [  
2.	    "spider_mojo/spider_mojo_impl.h",  
3.	    "spider_mojo/spider_mojo_impl.cc",  
4.	]  

2.注册接口

注:*号为前缀的代码行需新添加。

1.	//src/content/browser/frame_host/render_frame_host_impl.h
2.	...  
3.	*#include "services/spider_mojo/mojom/spider_mojo.mojom.h"
4.	*#include "content/browser/spider_mojo/spider_mojo_impl.h"  
5.	...  
6.	  
7.	namespace content {  
8.	...  
9.	*class LoggerImpl;  
10.	...  
11.	class CONTENT_EXPORT RenderFrameHostImpl{  
12.	public:  
13.	...  
14.	*void GetLogger(mojo::PendingReceiver<spider_mojo::mojom::Logger> receiver);  
15.	...  
16.	private:  
17.	...  
18.	*std::unique_ptr<LoggerImpl> logger_;  
19.	...  
20.	};  

1.	//src/content/browser/frame_host/render_frame_host_impl.cc  
2.	...  
3.	* void RenderFrameHostImpl::GetLogger(mojo::PendingReceiver<spider_mojo::mojom::Logger> receiver){  
4.	      * logger_ = std::make_unique<LoggerImpl>(std::move(receiver));  
5.	      * LOG(INFO) << "Launching Successfully";  
6.      *}
1.	//src/content/browser/browser_interface_binders.cc  
2.	...  
3.	* #include "services/spider_mojo/mojom/spider_mojo.mojom.h"  
4.	...  
5.	// Documents/frames  
6.	void PopulateFrameBinders(RenderFrameHostImpl* host,  
7.	                          service_manager::BinderMap* map) {  
8.	...  
9.	* map->Add<spider_mojo::mojom::Logger>(base::BindRepeating(  
10.	      &RenderFrameHostImpl::GetLogger,base::Unretained(host)));  
11.	...  
12.	}  

S3 编译

1.编译生成接口对应的源文件

​ 使用ninja编译目标:

1.	//在src/out/default目录下执行  
2.	ninja services/spider_mojo/mojom 

​ 执行完毕后,将会在src/out/Defaul/gen/service中生成相应的文件夹“spider_mojo”,该文件夹中包含生成的一些源文件:

2.编译content模块

​ 使用ninja编译:

1.	// 在src/out//Default目录下执行  
2.	ninja content  

​ 至此,大功告成,编译后会Log输出“hello”和 "Tail was: hello "

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值