个人对chromium mojo的理解
mojo本质是Uinx Domain Socket
(posix)在本机的进程间进行通信时不会经过网卡,可以少一次拷贝。
mojom的用途
主要用于进程间通信,减少模块间依赖。
用接口描述语言书写mojom接口文件,经过编译之后会自动生成对应的mojo类
mojo底层管道的创建
mojo的通信依赖于底层MessagePipe
,管道的创建在mojo/core/core.cc
中
core::CreateMessagePipe
,传入管道的两端handle
,这里的handle就是mojo handle了,管道创建成功并不意味着底层socket创建,发送invitation的时候才会真正创建socket
Node
网络
用于给mojo提供消息路由功能,在全局对象core中存在一个node_controller_
在创建MessagePipeDispatcher
的时候,会将NodeController
对象传入。
NodeController
持有Node
(由于全局对象core持有NodeController
是否说明NodeController
对象也是全局唯一?)
Node维护了一系列的Port,Port有name
NodeController
有一个peers_
的map,当收到invitation的时候(OnAcceptInvitation
)建立连接,并将对端存入这个map
using NodeMap = std::unordered_map<ports::NodeName, scoped_refptr<NodeChannel>>;
NodeMap peers_;
OnAcceptInvation
的实质是收到一个Message(来源于OnChannelMessage
)
发送邀请过程如下,A邀请B
(A)SendInvitation
->(A)AcceptInvitee
->(B)OnAcceptInvitee
->(B)AcceptInvitation
->(A)OnAcceptInvitation
->(A)AddPeer
,邀请结束,链接建立成功(两次握手)其中,AcceptInvitee
和AcceptInvitation
的消息都是通过NodeChannel
的Channel
对象发送消息
按照文档说明,node与node之间一开始只有IPC点对点通信,假如要发给另一个node,但是和当前node之间没有直接的IPC,则需要通过broker建立一个新的IPC通道,REQUEST_INTRODUCTION
消息就是这个过程
NodeChannel
和NodeName
一起保存在peers_
中。对上封装的接口,用于Node to Node的IPC接口。
NodeChannel::Introduce
负责介绍两个不认识的node相互认识(建立IPC通道)
也是在Invitation阶段创建的,和PlatformChannel一致,连接两端时创建
Channel
NodeChannel
对应的各平台实现,自身对象由NodeChannel
持有
NodeChannel::WriteChannelMessage
会通过Channel::Write
发送消息,对端信息包含在参数的message中,channel本身持有socket(posix),这个socket其实就是PlatformChannel
创建的,message参数中包含对端的PlatformHandle,这里的PlatformHandle其实是系统对应的handle,Windows的HANDLE,posix文件描述符,Handle里面存的就是最底层的通信手段,例如socket或者是管道
port
消息Messages在Ports的两端传输,一组Ports就代表了一个外层的MessagePipe
PlatformChannel
mojo底层用来通信的通道,本质是Unix Domain Socket
,在Core::SendInvitation
的时候创建底层的sockcet
Core::AcceptInvitation
时也会创建(Windows不是socket,而是named pipe)
public c system
to core
对外提供c接口,调用mojo使用这些接口,当调用这些接口时,将会通过dispatcher.cc
(抽象基础类,具体有不同的实现,例如MessagePipeDispatcher
)进行分发处理
对应接口的实现经过thunk.cc
转换后调用到core.cc
中的函数
在entrypoints.cc
中有全局变量g_thunks
来持有g_core
变量执行到core,完成函数转换这就完成了一次调用
dispatcher
dispatcher负责分发实现通用接口的不同实现方式,dispatcher在core内被创建时会存放到HandleTable
中,并返回对应的MojoHandle
例如MessagePipeDispatcher
就持有NodeController
,是由全局对象core传过来的
MessagePipeDispatcher
对象还持有一个port
,也是在一创建就传入的(由NodeController
和其Node
通过CreatePortPair
创建的,在CreateMessagePipe
的时候)
Broker
一个单独的node在node网络中被称作Broker,它的作用是
- 提供介绍机制(Introduce)帮助一对node建立IPC链接
- 复制node的handle(由于沙盒,node自身可能办不到)
- 创建共享内存
broker是个特殊的node channel,规定只有它能introduce(通过调用NodeController
的能力找到两个node)并发送Introduce message,这就要求broker需要跟每个node都有链接
在接受invitation和创建invitation的时候,例如在NodeController::OnAcceptInvitation
中,执行AddPeer
添加对端后,还给broker channel
添加了远端的client