X_session_manager

在 X Window 系統中，**X 對談管理器**是一個對談管理程式，這個程式能夠儲存和恢復一組程式的當前執行狀態。

## 概述

從 **X 對談管理器**的角度來看，一個對談是指給定時間的桌面狀態：一組窗口以及它當前的內容。更精確的說，一個對談是一組管理窗口或與窗口有關的客戶端以及允許這些程式恢復所需窗口的相關資訊。

使用對談管理器最顯著的效果是再次登入進入時所有窗口和狀態與登出時完全一致。為達到這一點，對談管理器程式儲存在登出時執行的程式名稱並在再次登入時啟動它們。此外，為了能較好的恢復程式的狀態 (恢復窗口內容是必需的)，當對談管理器要求時程式必須能儲存它們的執行狀態並在重新啟動時重新裝載它們。

通常，對談能在任意時刻儲存或裝載，即使使用者沒有登入或登出。儲存一系列不同的對談並按使用者的選擇裝載其中一個，這是可能的。也可以將一系列程式組合成一個對談。結果是，使用者能夠儲存一些不同的對談，也能儲存當前執行程式的狀態或明確的將一些程式組合為一個對談。這樣，使用者可稍後決定裝載某個對談。

為了能讓對談包括程式的狀態，程式必須能在適當的時候儲存和裝載它當前的狀態。_X 對談管理協定_ (XSMP) 指定程式與對談管理器該如何互動。特別重要的是視窗管理員能夠與對談管理器通信，因為視窗管理員對窗口的位置和最小化有管理的責任。不能儲存狀態的程式也包括在對談中，但它們不能在對談中維持自己的狀態。

X Window 系統包含了預設的對談管理器，名字叫 `xsm`。特定的桌面系統也開發了自己的對談管理器：例如，`ksmserver` 是 KDE 預設的對談管理器。

## 協定

XSMP 是客戶間交換協定的子協定。客戶端連接到對談管理器時開始協定。如何在網路中定位對談管理器是依賴系統的：對 POSIX 系統來說，環境變數包含了一個 `SESSION_MANAGER` 變數。因此，當客戶端開始時，`SESSION_MANAGER` 變數必須是適當的值。

### 識別碼

該協定要考慮兩方面：

1. 為了能讓對談正確的重新啟動，不但程式必須重新啟動，而且它們必須以這樣一種方式恢復原先的狀態；
2. 同樣的程式可能在同一個對談或不同對談中多次執行。

同一個程式的不同實例可能會在同一個或不同對談中同時執行，這些對談大多具有不同的執行狀態。例如，使用者可用文字編輯器打開 `/etc/passwd` 檔案，同時在同一個對談中打開 `letter.txt` 檔案，在另一個對談中打開 `todo.txt` 檔案。

為了能完全的恢復對談，對談管理器必須認定同一個程式的不同實例是不同的。基於這一原因，對談管理器為每一個程式的每一個實例選擇一個唯一的識別碼。這樣，對談管理器就能區分打開 `/etc/passwd` 檔案和打開 `todo.txt` 檔案的文字編輯器，即使他們是相同程式的兩個實例。

識別碼必須唯一。特別是，在由對談管理器管理的所有對談中他們也必須是唯一的：打開 `/etc/passwd` 檔案的文字編輯器的識別碼不僅不同於打開 `letter.txt` 檔案的文字編輯器的識別碼，而且不同於在另一個對談中打開 `todo.txt` 檔案的文字編輯器的識別碼。即使對談關閉和重新啟動，客戶端的識別碼保持相同。

### 協定主體

對談管理協定的主要部分是：

1. 對談管理器為每個客戶端選擇一個唯一的識別碼
2. 對談管理器需要客戶端儲存他們的狀態
3. 客戶端指定它該如何重新啟動以便恢復狀態（例如，使用命令列來啟動程式）

最後一點是可行的，因為對談管理器維護每個客戶端的一組屬性（在 X Window 系統中，屬性是資料的簡單容器）。客戶端可在任何時刻修改資訊。其中一個屬性是 `RestartCommand`，它指示客戶端如何重新啟動。

當對談管理器需要客戶端儲存其狀態時，程式按以下步驟執行：

1. 以一種方式儲存其狀態，兩個不同實例的狀態必須區分；儲存狀態的檔案的名字以它的識別碼構成，這樣就可區分不同實例
2. 在 `RestartCommand` 屬性中儲存重新啟動該程式的方法；該屬性必須包含客戶端識別碼，因為：
  1. 程式必須在重新啟動時保持其識別碼
  2. 儲存狀態時需要用到識別碼（例如，使用識別碼尋找狀態儲存在哪個檔案）

除了 `RestartCommand`，對談管理器還維護其他屬性。例如，有一個屬性指示，當對談銷毀時，如何執行程式。

### 本地和全域狀態

當請求客戶端儲存狀態時，視窗管理員會指定儲存本地狀態還是全域狀態，或者都儲存。兩者的區別是儲存的狀態對其他程式是否可見。

以文字編輯器為例，儲存全域狀態意味著正常儲存檔案，其他程式都能看到被文字編輯器修改後的新檔案。儲存本地狀態意味著儲存一個檔案的本地複本，其他程式都看不到檔案新修改的部分。

### 一個例子

以下是超文字編輯器 `xyx` 和對談管理器互動時的主要步驟，情景是當超文字編輯器在對談中第一次啟動，然後使用者登出，最後使用者再次登入：

1. 超文字編輯器通用客戶間交換協定連接到對談管理器
2. 超文字編輯器告訴對談管理器這是它第一次啟動，因此它沒有識別碼（也因此，沒有先前的狀態）
3. 對談管理器分配給它一個唯一的識別碼，比如 `4324`
4. 對談管理器立即要求超文字編輯器儲存它的本地狀態（只儲存本地狀態，因為它第一次啟動）
5. 超文字編輯器在對談管理器的 `RestartCommand` 屬性中儲存一段命令列代碼 `xyz -sid 4324`（這是依賴特定系統的：在 POSIX 系統中，這個屬性會用於 argv 環境參數陣列中）
6. 超文字編輯器儲存它的本地狀態；例如，可能儲存編輯文字的名字和其他所有資訊（比如當前行）到本地 `.temp-4324` 檔案中
7. 當使用者登出時，對談管理器傳送資訊給所有客戶端通知它們儲存各自的狀態
8. 超文字編輯器（識別碼為 `4324`）再次答應
9. 當所有客戶端通知對談管理器狀態已儲存，對談管理器就會關閉對談

當客戶端被告知要儲存狀態時，它有可能還能與使用者進行有限的互動（例如，詢問使用者是否儲存正在編輯的檔案）。不管怎樣，狀態儲存後，它會向對談管理器傳送適當的訊息。

當對談再次啟動時，發生以下步驟：

1. 對談管理器執行儲存在 `RestartCommand` 屬性中的代碼以此重新啟動識別碼為 `4324` 的客戶端
2. 因此以執行命令列 `xyz -sid 4324` 的方式啟動超文字編輯器；這樣，超文字編輯器就知道自己的識別碼
3. 超文字編輯器從 `.temp-4324` 檔案中找回狀態資訊
4. 超文字編輯器連接對談管理器，指明自己的識別碼為 `4324`，以便對談管理器得知其不是新啟動的程式

## 客戶端管理對談

依照 XSMP 協定，只要能夠執行和控制其他程式狀態的程式都可以是對談管理器。所以，一個客戶端本身可以成為其他客戶端的對談管理器。例如，Email 客戶端能啟動一個文字編輯器來編寫郵件，並在編輯器前表現的像對談管理器。因此，如果電子郵件客戶端並閉後再啟動時，它能恢復文字編輯器的狀態。

## 歷史

GNOME 的對談管理器用 D-Bus (版本 2.24.) 取代了 XSMP

## 參見

* X Window 系統的協定和架構
* X 視窗管理員

## 參考文獻

## 外部連結

* X 對談管理協定
* xsm 手冊 （頁面存檔備份，存於網際網路檔案館）
* ksmserver （頁面存檔備份，存於網際網路檔案館），KDE 對談管理器
* ROX-Session （頁面存檔備份，存於網際網路檔案館），ROX Desktop 對談管理器