本文件說明元件嘗試執行 連線至命名空間中的通訊協定
這些步驟適用於 元件 執行時 進入 App Engine 應用程式
大致步驟如下:
- 元件管理員會建構元件的命名空間
,根據其資訊清單中的
use
宣告內容。 - 執行後,元件會嘗試開啟通訊協定 命名空間
- 元件管理員會收到這項
Open
要求,並執行必要的功能路由,找出提供該通訊協定的元件。 - 元件管理員會繫結至提供通訊協定的元件
並將
Open
要求與其連線
建構元件的命名空間
命名空間是一組目錄,會在元件啟動時提供給該元件。每個目錄都會與檔案系統路徑建立關聯,讓元件可透過該路徑存取其他元件提供的檔案和通訊協定。
這些目錄會以帳號代碼的形式呈現到頻道,
所有元件都能使用
fuchsia.io.Directory
FIDL 通訊協定。
例如,所有元件都會獲得套件內容的控制代碼
也就是建立在 /pkg
時建立的來源。這表示元件可以透過讀取 /pkg/bin
的內容,查看套件中可用的二進位檔。
元件資訊清單中的 use
宣告
決定命名空間的填入方式。使用通訊協定能力時...
use: [
{
protocol: "fuchsia.example.Foo",
},
]
...元件管理員會將項目新增至
通訊協定的父項目錄在這個範例中,
通訊協定為 /svc/fuchsia.example.Foo
(預設路徑指派),
這表示元件管理員會將 /svc
的控制代碼新增至命名空間。
/svc
目錄是由元件管理器本身提供,元件管理器會在元件生命週期內回應對此目錄的通訊協定要求。
命名空間中顯示的確切語意會因功能類型而異。例如,如果使用目錄能力而非通訊協定 能力...
use: [
{
directory: "example-data",
rights: [ "r*" ],
path: "/example/data",
},
]
...在命名空間中顯示目錄本身的控制代碼,而非
做為父項目錄的處理常式。在此範例中,這表示
/example/data
會顯示在命名空間中,如果這個路徑用於
通訊協定能力 /example
會顯示在命名空間中
元件開啟通訊協定
當元件想要開啟通訊協定時,系統會建立新的管道組合,以及
透過 管道中的管道,透過 Open
要求來傳送此組合的一端
命名空間舉例來說,如果元件想要開啟與 /svc/fuchsia.example.Foo
的連線,新管道組的其中一端會透過其命名空間中的 /svc
句柄傳送。接著,元件可能會透過管道呼叫 fuchsia.example.Foo
通訊協定。
由於包含通訊協定 (/svc
) 的目錄是由元件提供
這個元件是元件管理員,負責接收新的
透過元件傳送的 Open
要求傳送管道。接著,元件管理員
必須指明透過這個管道提供通訊協定的元件。
Open
會觸發能力轉送
如要判斷透過管道提供通訊協定的元件,元件管理員必須依序檢查 offer
和 expose
宣告,沿著元件樹狀結構尋找功能的來源。這項程序
視為功能轉送。
元件管理員會從觸發功能路由的元件父項開始,檢查每個元件的資訊清單,尋找目的地與子項相符的 offer
宣告。方案會指定 parent
、self
或子項的來源。如果提案來自
這些元件會不斷延伸到樹狀結構中
從元件的其中一個子項中,沿著樹狀結構向下走至該子項。
一旦路由開始沿著樹狀結構往下走,就會尋找 expose
宣告,並指定 self
或子項名稱的來源。如果能力來自子項,元件管理員會繼續沿著樹狀結構下移。
找到含有 self
來源的 offer
或 expose
宣告後,
元件管理工具則能將管道交給該元件。
如果在鏈結無效的任何步驟中無效,元件管理員會記錄
即可關閉來自 Open
呼叫的管道。這可能是因為
各種不同的情境,包括
- 元件
C
提供來自parent
的能力,但其父項R
有提供 不提供C
能力。 - 元件
C
提供來自子項D
的能力,但子項D
確實 不會向C
公開能力。
舉例來說,請考慮下列元件樹狀結構及其資訊清單 (為了簡化說明,省略 program
區塊和執行程式設定):
C
/ \
B D
/
A
A.cml:
{
// ...
capabilities: [
{
protocol: "fuchsia.example.Foo",
},
],
expose: [
{
protocol: "fuchsia.example.Foo",
from: "self",
},
],
}
B.cml:
{
// ...
expose: [
{
protocol: "fuchsia.example.Foo",
from: "#A",
},
],
children: [
{
name: "A",
url: "fuchsia-pkg://fuchsia.com/a#meta/a.cm",
},
]
}
C.cml:
{
// ...
offer: [
{
protocol: "fuchsia.example.Foo",
from: "#B",
to: [ "#D" ],
},
]
children: [
{
name: "B",
url: "fuchsia-pkg://fuchsia.com/b#meta/b.cm",
},
{
name: "D",
url: "fuchsia-pkg://fuchsia.com/d#meta/d.cm",
},
]
}
D.cml:
{
// ...
use: [
{
protocol: "fuchsia.example.Foo",
},
],
}
當 D
在其命名空間中對 /svc/fuchsia.example.Foo
呼叫 Open
時,元件管理員會逐一檢查樹狀結構,找出應提供此通訊協定的元件。開始時間為D
的父項 C
,從這裡開始:
- 找出
fuchsia.example.Foo
至D
的offer
宣告,並參閱 這個編號來自B
子項 - 找出
B
的fuchsia.example.Foo
的expose
宣告, 您會看到它來自A
- 找出
A
的fuchsia.example.Foo
的expose
宣告, 您會看到它來自self
也就是說,A
是元件 提供了D
要使用的能力
找到提供者元件後,元件管理員可以嘗試透過 Open
要求,將收到的管道交給其他元件。
繫結至元件並傳送通訊協定管道
供應商找到後,用戶端元件現已繫結至供應商。如果元件目前已停止,這會導致元件開始執行。
啟動後的每個元件都會收到一個伺服器控制代碼,
傳出目錄
。
元件繫結時,元件管理員會轉送
設為提供元件的傳出目錄,位於
來源路徑。offer
或 expose
宣告中。
在上述範例元件管理員中,系統會透過Open
元件 A
至 /svc/fuchsia.example.Foo
的傳出目錄控制代碼
路徑,並在該路徑提供從元件 D
接收的頻道帳號代碼
名為 Open
的元件管理員
然後,A
元件才能接收這項要求並開始回應
或「接收」通知
因為元件管理員會直接轉送通訊協定管道的伺服器端 到提供者元件的傳出目錄,則與訊息無關 且在能力轉送 已完成與其他元件建立連線後 彼此之間沒有仲裁元素
注意事項
執行階段的不確定性
由於能力導向的執行階段特性和提供能力的元件行為,我們無法得知特定元件是否能在嘗試存取能力之前,成功存取其命名空間中的功能。即使能力有有效的提供/公開鏈結,套件更新也可能會在執行階段中斷鏈結,因此聲稱在其資訊清單中提供能力的元件,在執行時可能無法提供能力。
提供與微光功能
部分功能是由元件架構本身提供,可直接由元件使用 (或會隱含提供給元件),而不需要元件的父項提供這些功能。目前有:
/pkg
:建立元件的來源套件控制代碼。/svc/fuchsia.component.Realm
:一種通訊協定,可供元件使用 並管理自己的領域