通訊協定的效期

本文件說明元件嘗試執行 連線至命名空間中的通訊協定

這些步驟適用於 元件 執行時 進入 App Engine 應用程式

大致步驟如下:

建構元件的命名空間

命名空間是一組目錄,會在元件啟動時提供給該元件。每個目錄都會與檔案系統路徑建立關聯,讓元件可透過該路徑存取其他元件提供的檔案和通訊協定。

這些目錄會以帳號代碼的形式呈現到頻道, 所有元件都能使用 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 會觸發能力轉送

如要判斷透過管道提供通訊協定的元件,元件管理員必須依序檢查 offerexpose 宣告,沿著元件樹狀結構尋找功能的來源。這項程序 視為功能轉送

元件管理員會從觸發功能路由的元件父項開始,檢查每個元件的資訊清單,尋找目的地與子項相符的 offer 宣告。方案會指定 parentself 或子項的來源。如果提案來自 這些元件會不斷延伸到樹狀結構中 從元件的其中一個子項中,沿著樹狀結構向下走至該子項。

一旦路由開始沿著樹狀結構往下走,就會尋找 expose 宣告,並指定 self 或子項名稱的來源。如果能力來自子項,元件管理員會繼續沿著樹狀結構下移。

找到含有 self 來源的 offerexpose 宣告後, 元件管理工具則能將管道交給該元件。

如果在鏈結無效的任何步驟中無效,元件管理員會記錄 即可關閉來自 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.FooDoffer 宣告,並參閱 這個編號來自 B 子項
  • 找出 Bfuchsia.example.Fooexpose 宣告, 您會看到它來自 A
  • 找出 Afuchsia.example.Fooexpose 宣告, 您會看到它來自 self也就是說,A 是元件 提供了 D 要使用的能力

找到提供者元件後,元件管理員可以嘗試透過 Open 要求,將收到的管道交給其他元件。

繫結至元件並傳送通訊協定管道

供應商找到後,用戶端元件現已繫結至供應商。如果元件目前已停止,這會導致元件開始執行。

啟動後的每個元件都會收到一個伺服器控制代碼, 傳出目錄 。 元件繫結時,元件管理員會轉送 設為提供元件的傳出目錄,位於 來源路徑。offerexpose 宣告中。

在上述範例元件管理員中,系統會透過Open 元件 A/svc/fuchsia.example.Foo 的傳出目錄控制代碼 路徑,並在該路徑提供從元件 D 接收的頻道帳號代碼 名為 Open 的元件管理員

然後,A 元件才能接收這項要求並開始回應 或「接收」通知

因為元件管理員會直接轉送通訊協定管道的伺服器端 到提供者元件的傳出目錄,則與訊息無關 且在能力轉送 已完成與其他元件建立連線後 彼此之間沒有仲裁元素

注意事項

執行階段的不確定性

由於能力導向的執行階段特性和提供能力的元件行為,我們無法得知特定元件是否能在嘗試存取能力之前,成功存取其命名空間中的功能。即使能力有有效的提供/公開鏈結,套件更新也可能會在執行階段中斷鏈結,因此聲稱在其資訊清單中提供能力的元件,在執行時可能無法提供能力。

提供與微光功能

部分功能是由元件架構本身提供,可直接由元件使用 (或會隱含提供給元件),而不需要元件的父項提供這些功能。目前有:

  • /pkg:建立元件的來源套件控制代碼。
  • /svc/fuchsia.component.Realm:一種通訊協定,可供元件使用 並管理自己的領域