アイトークプロトコル0.9/1.0仕様書(案)

かきかけです。 大幅に変更になる可能性があります。 http://www.st.rim.or.jp/~mina/italk_log/19981207.italkも参照。


目次

  1. 要旨
  2. 用語
  3. 概要
  4. サーバー情報の形式
  5. 主プロトコル
  6. 副プロトコル
  7. セキュリティ
  8. 参考文献・関連ソフトウェア

要旨

本仕様書は、アイトークのサーバー・クライアント間のプロトコルを規定し、 実装の助けとする。 プロトコルはバージョン0.9と1.0がある。 各バージョンに固有の事項には、[0.9][1.0]の印を付ける。


用語

アイトーク(Italk)
本仕様書で規定するプロトコルによりネットワーク上での会話を実現するシステム。
会話(chat)
アイトークシステムにより利用者が情報交換をすること。
サーバー(server)
アイトーク利用者の会話を収集・配送・蓄積するプログラム。 一つのアイトークシステムにサーバーは一つ存在する。
クライアント(client)
アイトークプロトコルによってサーバーに接続するプログラム。 アイトークの利用者が、サーバーとの間で会話情報を伝達するために、 またはアイトークの利便性向上などのために使用する。 狭義には、主プロトコルによって利用者の会話を伝達するもののみを指し、 人工無能やビフクライアントは含まない。 利用者はクライアントを通じてサーバーで会話するため、 クライアントと利用者はしばしば同一視される。 特に区別する場合、「クライアントプログラム」と呼ぶことにする。
人工無能・人工無脳(bot)
主プロトコルを使用するクライアントの一種。 実際には利用者の会話を伝達していないにもかかわらず、 自律的に振る舞ってあたかもそのように見せかけたり、 あるいは他のクライアントからの指示により何らかの機能を実現するものを指す。
ビフクライアント(biff client)
クライアントの一種で、 副プロトコルによってサーバー情報を収集し利用者に提示するクライアントを指す。 サーバーの状況の変化を随時表示するところが、 UNIXのbiffコマンドを思わせるため、この名前がある。
擬似クライアント(pseudoclient)
サーバー組み込みの機能で、 あたかも架空のクライアントが存在して振る舞っているかのように動作するもの。 実際にそのようなクライアントがログインしているわけではないので、 クライアントの定義には含まれない。 主に、人工無能によって実現されていた機能をサーバーに組み込んだ際、 従来の動作との機能的ないし慣習的互換性をとるために用いられる。 利用者の混乱を防ぐため、擬似クライアントのハンドルは公知でなければならない。 また、その振る舞いは最小限にとどめるべきである。
[1.0]クライアントタイプ(client type)
クライアントの種類。 クライアントはネゴシエーションコマンドにより自分のタイプを宣言することができ、 それによってサーバーが送信する下りの情報が変化する。
ID下りデータ想定されるクライアントの例
ログサーバー情報差分
null なしなしログを読まない人工無能
normal ありなしTELNETクライアント、
普通のクライアント、
ログを読む人工無能
biff なしありビフクライアント
mixed ありあり高機能クライアント
ハンドル(handle)
クライアントが名乗る名前。通常のクライアントでは、 それを使って発言する利用者の名前を表す。 人工無能では、通例としてその人工無能の機能を表す適当な名前をつける。
利用者番号(user number)
サーバーが各クライアントに付与する固有の番号。 採番方法は実装依存である。電報で使用する。
上り(upstream)
クライアントからサーバーへの情報伝達。
下り(downstream)
サーバーからクライアントへの情報伝達。
ホスト(host)
サーバーまたはクライアントが動作しているコンピューター。
発言(speech)
利用者がクライアントを介してサーバーに伝達する情報のうち、 ログイン中の全クライアントに即時に配布されることを意図しているもの。
ログイン(login)
あるクライアントがサーバーに接続して会話に参加すること。
[1.0]仮ログイン(informal login)
クライアントがサーバーとの接続を確立したが、 まだハンドルを名乗っていない状態のこと。 一部のコマンドの使用のみ可能。 仮ログイン中のクライアントは、発言・電報・伝言・アナウンスなどで他のクライアントにはたらきかけることはできない。 また、仮ログイン中のクライアントの行動は、他のクライアントからはわからない。
[1.0]正式ログイン(formal login)
仮ログインの後、ハンドルを名乗ること。発言と全コマンドの使用が可能。
ログアウト(logout)
あるクライアントがサーバーに接続しているとき、 そのクライアントからの要求により接続が切断されて会話を終了すること。
強制切断(forced disconnection)
あるクライアントがサーバーに接続しているとき、 何らかの障害によりサーバーまたはクライアントが接続を強制的に切断すること。
セッション(session)
あるクライアントのログインからログアウトまたは強制切断までの間。
ステータス(status)
クライアントが自分の状況を他のクライアントに示すために伝達する情報。 サーバーはこれを他のクライアントに伝達するが、サーバー自身の機能には関係しない。
電報(telegram)
利用者がクライアントを介してサーバーに伝達する情報のうち、 指定したクライアントのみに即時に配布されることを意図し、 他の利用者に知られることを意図していないもの。
表伝言(open message)
発言のうち、その時ログインしていない特定のクライアントが後でログインしたときに そのクライアントに伝達されることを意図しているもの。
裏伝言(secret message)
利用者がクライアントを介してサーバーに伝達する情報のうち、 その時ログインしていない特定のクライアントが後でログインしたときに そのクライアントに伝達されることを意図し、 他の利用者に知られることを意図していないもの。
伝言(message)
表伝言および裏伝言。
アナウンス(announcement)
全クライアント(それ以降ログインするものも含めて)に対して行う告知。 アナウンスが行われたときにログインしていなかったクライアントが後でログインした場合、 アナウンスの内容が伝達される。 アナウンスはサーバーに蓄積されるが、一定期間が過ぎると自動的に消滅する。
コマンド(command)
クライアントからサーバーに対して発行する命令。 ハンドル変更・ステータス変更・電報・裏伝言・アナウンス・ヘルプ・ログ取得・ クライアント情報取得・ログアウトなど。
コマンド文字(command prefix)
上りの行において、コマンドと発言を区別するため、 コマンドの先頭に記述する特定の文字。
再生(replay)
伝言またはアナウンスの伝達対象となるクライアントがログインしたときに、 サーバーがクライアントにこれを伝達すること。 表伝言の再生は擬似クライアントの発言として行ってもよい。 裏伝言とアナウンスの再生はシステム出力で行う。
イベント(event)
サーバー起動・ログイン・ログアウト・強制切断・ステータス変更・ ハンドル変更・アナウンスなどが発生すること。
ログ(log)
発言やイベントをその時刻やハンドルとともに記録したもの。 サーバーがログイン中の全クライアントに送信するとともにファイルに記録する。
バックログ(back log)
クライアントの要求に応じてサーバーが再度送信するログのこと。
システム出力(system output)
ログ以外の下りの情報。 電報・伝言やアナウンスの再生・コマンドに対する応答など。 特定のクライアントにのみ送信される。
サーバー情報(server information)
動作中のサーバー、およびそのサーバーにログインしているクライアントに関する詳細な各種情報のこと。 コマンド応答または副プロトコルによってクライアントに提供される。 [1.0]タイプbiffおよびmixedのクライアントには差分情報が提供される。
[0.9]主プロトコル(primary protocol)
サーバーとクライアント(利用者)の間の会話情報の伝達を目的とするプロトコル。
[0.9]副ブロトコル(auxiliary protocol)
サーバーからビフクライアントへのサーバー情報の提供を目的とするプロトコル。 主プロトコルとは別の通信路を使用する。

概要

システムモデル

アイトークシステムは、一つのサーバーと一つ以上のクライアントから構成される。 クライアントはサーバーにログインし、 両者はプロトコルを用いて会話情報の伝達を行う。 上りの情報は、発言・コマンドなどであり、 下りの情報は、発言・イベント・電報・伝言やアナウンスの再生・ コマンドに対する応答・サーバー情報などである。

サーバー・クライアント間の接続は、 信頼性のある接続指向の通信路を仮定する。

会話の空間はサーバーごとに一つとする。

サーバーは、クライアントを認証しない。 クライアントは、電報においては利用者番号、 伝言・アナウンスにおいてはハンドルにより識別される。 同一ハンドルのクライアントが複数ログインしてもよい。 なお、伝言・アナウンスにおいてサーバーがハンドルを照合する際の規則は実装依存とする。 とくに、英字の大小文字は同一視される場合がある。

特別に設計されたクライアントは、 複数のサーバーに同時にログインすることも可能である。 また、そのようなクライアントがサーバー間でログを中継することにより、 複数サーバーにまたがった会話を実現することも可能である。 しかし、このような利用形態も上記のモデルを逸脱するものではないので、 本仕様では積極的には考慮しない。

プロトコルの概要

本仕様書では、サーバー・クライアント間の通信プロトコルを規定する。 サーバーおよびクライアントの内部の挙動や、 サーバーが利用者に対して送信する可読文の詳細については、 実装依存としてここでは規定しない。

[0.9]プロトコルは、主プロトコル(必須)と副プロトコル(オプション)がある。 どちらも可読文字で構成される行指向のプロトコルである。 TCPを使用する場合、デフォルトのポート番号は、 主プロトコルは12345、副プロトコルはそれより1小さい番号とする。

[1.0]プロトコルは可読文字で構成される行指向のプロトコルである。 TCPを使用する場合、デフォルトのポート番号は12345とする。 0.9の副プロトコルを利用する従来の実装との互換性のため、 1小さいポート番号を同時に使用してもよい。

プロトコルにより通信される情報は下図のように分類される。

               ┌─ハンドル(ログイン時のみ)
               │
          ┌─上り─┼─発言
          │    │
          │    └─コマンド
          │
          │
主プロトコル────┤
          │             ┌─発言
          │    ┌─ログ─────┤
          │    │        └─イベント
          │    │
          └─下り─┤
               │        ┌─電報
               │        │
               │        ├─裏伝言・アナウンス再生
               ├─システム出力─┤
               │        ├─コマンド応答
               │        │
               │        └─その他(各種通知など)
               │
               └─[1.0]サーバー情報差分


            ┌─上り───切断要求
[0.9]副プロトコル─┤
            └─下り───サーバー情報

文字コード系

ここでは、サーバー・クライアント間の情報伝達に使われる文字コード系について規定する。

文字コード系はISO 2022系の文字集合・エンコーディングを基本とする。 上りのコード系は*junet*または*euc-japan*のどちらか、 またはこれらの混合を使用する。 サーバーはシフトJISとの自動判別をしてもよい。 下りのコード系は*euc-japan*([1.0]または*junet*のどちらか)を使用する。

下りの行末コードはCR/LFとする。 [0.9]上りの行末コードは、CR/LFまたはLFとする。 [1.0]上りの行末コードは、CR/LF、CR、LF、またはCR/NULとする。

以上のコード系および行末コードは、 サーバーとクライアントの合意によりセッション中変更することができる。 ISO 10646/Unicodeを使用する場合はUTF-8でエンコードすることが望ましい。

クライアントはTELNETプロトコルに定めるTELNETコマンドコード(0xFFで始まる)を送信してもよい。 受信したサーバーは、文字コードの解釈に先だってTELNETコマンドコードを 解釈あるいは廃棄(ただし0xFF 0xFFは単一の0xFFに変換)しなくてはならない。 このため、TELNETコマンドコードを送らないクライアントも、 文字コードとして0xFFを送る場合は0xFF 0xFFとして送ることが望ましい。 サーバーはクライアントに対してTELNETコマンドコードを送るべきではない。

サーバーとクライアントは、受信した行の中に、 動作に支障をきたすおそれのある文字がある場合、 その文字を適宜変換または廃棄してもよい。

サーバーとクライアントは以下の文字集合をサポートしなければならない。

サーバーとクライアントは、ISO 2022の指示および呼び出しのシーケンスを解釈し、 以下の文字集合をサポートすることが望ましい。

サーバーは以下の私用コードを保存することが望ましい。

サーバーとクライアントは、慣習的に混同あるいは同一視されることの多い文字集合を同一視して扱ってもよい (US-ASCIIとJIS X 0201ローマ文字、JIS C 6226-1978とJIS X 0208-1983/1990/1997など)。


サーバー情報の形式

サーバー情報の形式を以下に定義する。空行が入ることがある。

[0.9]サーバー情報の形式は副ブロトコルと利用者一覧コマンド('a'指定時)に共通であるが、 副プロトコルでは対面セクションは省略される。

[1.0]サーバー情報は利用者一覧コマンド('a'指定時)でのみ取得できる。 クライアントタイプがbiffまたはmixedの場合、各行(空行も含む)の先頭に"#! "がつく。

{サーバー情報} ::=
	"<italk>" {EOL}
	{サーバーセクション}
	[ {対面セクション} ]
	[ {クライアントセクション}... ]
	"</italk>" {EOL}

{サーバーセクション} ::=
	"<server>" {EOL}
	[ {サーバーセクション行}... ]
	"</server>" {EOL}

{対面セクション} ::=
	"<you>" {EOL}
	{対面セクション行}
	"</you>" {EOL}

{クライアントセクション} ::=
	"<user>" {EOL}
	[ {クライアントセクション行}... ]
	"</user>" {EOL}

{サーバーセクション行} ::=
	"version=" {サーバー実装バージョン} {EOL} |
	"host=" {ホスト名} {EOL} |
	"port=" {TCPポート番号} {EOL} |
	"users=" {クライアント数} {EOL} |
	"boottime=" {time_t型日時} {可読日時} {EOL} |
	"currenttime=" {time_t型日時} {可読日時} {EOL} |
	"uptime=" {秒数} {EOL} |
	"admin=" {管理者名} {EOL} |
	"logcode=" {コード系名} {EOL} |
	{セクション行}

{対面セクション行} ::=
	"userno=" {利用者番号} {EOL} |
	{セクション行}

{クライアントセクション行} ::=
	"userno=" {利用者番号} {EOL} |
	"uptime=" {秒数} {EOL} |
	"idle=" {秒数} {EOL} |
	"handle=" {ハンドル} {EOL} |
	"host=" {ホスト名} {EOL} |
	"status=" {ステータス} {EOL} |
	"upcode=" {コード系名} {EOL} |
	"downcode=" {コード系名} {EOL} |
	{セクション行}

{セクション行} ::= {キーワード} '=' {値} {EOL}

主プロトコル

ログイン時の流れ

プロトコル0.9

  1. クライアントがサーバーに接続する。
  2. サーバーはクライアントにバナーを送信する。
  3. クライアントはサーバーにハンドル行を送信する。
  4. サーバーはクライアントの正式ログイン処理をする。

プロトコル1.0

仮ログイン(全クライアントタイプ共通)

  1. クライアントがサーバーに接続する。
  2. サーバーはクライアントにバナーを送信する。 バナーの先頭行は以下の形式である。 クライアントはこの行を検出してプロトコルのバージョンを知る。
    # Italk Protocol x.x
    
  3. これ以降、クライアントは仮ログインで使用可能なコマンドを送信してもよい。

クライアントタイプnormalの場合

  1. クライアントはネゴシエーションコマンドでクライアントタイプnormalを宣言してもよい。
  2. クライアントはサーバーにハンドル行またはハンドル設定コマンドを送信する。
  3. サーバーはクライアントの正式ログイン処理をする。
  4. これ以降、クライアントは発言およびすべてのコマンドの使用が可能となり、 サーバーはログの送信を開始する。

クライアントタイプbiffの場合

  1. クライアントはネゴシエーションコマンドでクライアントタイプbiffを宣言する。
  2. これ以降、サーバーはサーバー情報差分の送信を開始する。
  3. クライアントはサーバーにハンドル行またはハンドル設定コマンドを送信してもよい。 その場合サーバーは正式ログイン処理をし(バックログは送信しない)、 クライアントは発言およびすべてのコマンドの使用が可能となるが、 サーバーは依然としてログを送信しない。

クライアントタイプmixedの場合

  1. クライアントはネゴシエーションコマンドでクライアントタイプmixedを宣言する。
  2. これ以降、サーバーはサーバー情報差分の送信を開始する。
  3. クライアントはサーバーにハンドル行またはハンドル設定コマンドを送信する。
  4. サーバーはクライアントの正式ログイン処理をする。
  5. これ以降、クライアントは発言およびすべてのコマンドの使用が可能となり、 サーバーはログの送信を開始する。

クライアントタイプnullの場合

  1. クライアントはネゴシエーションコマンドでクライアントタイプnullを宣言する。
  2. クライアントはサーバーにハンドル行またはハンドル設定コマンドを送信する。
  3. サーバーはクライアントの正式ログイン処理をする(バックログは送信しない)。
  4. これ以降、クライアントは発言およびすべてのコマンドの使用が可能となるが、 サーバーは依然としてログを送信しない。

上りの最初の行([0.9]ハンドルであるはずのもの)が、 明らかに他の何らかのアプリケーションプロトコルであると認められる場合 (例えばHTTPのGETリクエスト行と認められる場合)には、 サーバーは通信を強制切断するか、当該プロトコルでの通信を試みるなどの対応をとってもよい。

[0.9]上りの最初の行(ハンドルであるはずのもの)がログアウトコマンドの形式に一致する場合、 サーバーはクライアントが接続を取り消したものとみなして切断してもよい。

上りの行の先頭バイトが0x04(コントロールD)である場合、 サーバーはログアウトコマンドと同様に処理してもよい。

ハンドルが空である場合、 サーバーは適当なデフォルトハンドルが入力されたものとみなしてログイン処理をする。

クライアントタイプはセッションの途中で変更することも可能。

セッション中の流れ

ログアウト時、クライアントはサーバーが接続を切断したことを検出してから接続を切断するべきである。

クライアントおよびサーバーは、相手との間に通信障害が発生した場合、 接続を強制切断することができる。 いずれの場合もサーバーは他のクライアントに対してこれをイベントとして通知しなくてはならない。

ログ

ログ(発言とイベント)のフォーマットはここでは規定しない。 ただし、先頭の文字は#であってはならない。 サーバー起動イベントは例外的に先頭の文字を#とする。

発言には、発言者のハンドル・発言時刻・発言本文を含む。 イベントには、イベントの内容を示す可読文・イベント発生日時・ イベント発生者ハンドル(もしあれば)を含む。

サーバーは、クライアントからの発言によらず、 組み込みの擬似クライアントの発言を生成して送信してもよい。

システム出力

サーバー情報以外のシステム出力は下記のいずれかのフォーマットに従う。 いずれも先頭の文字は#である。 サーバー情報は別途規定するフォーマットに従う。

#形式

# 可読文

サーバーから利用者への各種の通知を行う。

#形式は、一時的な情報であり、 利用者は読んだあと捨ててもかまわないと考えられる行を示す。

#>形式と#<形式

#> 可読文

電報の発信者に対して、 受信者および電報本文をエコーし、 電報を送ったことを通知する。

裏伝言の発信者に対して、 受信者および裏伝言本文をエコーし、 裏伝言を受理したことを通知する。

#< 可読文

電報の受信者に対して、 送信者および電報本文を通知する。

裏伝言の受信者に対して、 裏伝言を再生する(発信者、発信日時および裏伝言本文)。

#>形式と#<形式は、 利用者が電報や裏伝言の送受信状況をログとともに保存したい場合に、 最低限保存する必要のある行を示す。

##形式

## 可読文

バックログ先頭・末尾マーカーを示す。

##形式は、マーカーに挟まれたバックログを削除しても、 ログの情報に欠損が生じないようになっていなければならない。

[1.0]サーバー情報差分

いずれかのクライアントに関して正式ログイン・ログアウト・強制切断・ ステータス設定・ハンドル設定が行われると、 サーバーは、タイプbiffおよびmixedの全クライアント(ログイン・ログアウト・強制切断の場合、そのクライアント自身は除く)に対して、 サーバー情報の差分を以下の形式で提供する。 各行の先頭には"#! "がつく。

{差分} ::= {ログイン情報} | {ハンドル情報} | {ステータス情報} | {ログアウト情報} | {強制切断情報}

{ログイン情報} ::=
	"<newuser>" {EOL}
	[ {ユーザーセクション行}... ]
	"</newuser>" {EOL}

{ハンドル情報} ::=
	"newhandle=" {番号} ',' {ハンドル} {EOL}

{ステータス情報} ::=
	"newstatus=" {番号} ',' [ {ステータス} ] {EOL}

{ログアウト情報} ::=
	"logout=" {番号} {EOL}

{強制切断情報} ::=
	"disconnect=" {番号} {EOL}

サーバー情報を利用するクライアントは、 まず利用者一覧コマンド('a'指定)によって全サーバー情報を取得し、 その後サーバー情報差分により随時これを更新する。

発言

ログイン後の上りの行のうち、コマンド文字で始まらないものは発言とみなされる。 空行も発言として有効である。 コマンド文字で始まるものでも発言として扱われる場合がある。

発言に表伝言が含まれる場合、サーバーはこれを適切に処理する。 ただし、サーバーは、特定のハンドルをもつクライアントによる表伝言を無視することができる。 これは、サーバー間でログを中継する人工無能を使用している場合に、 あるサーバーで発せられた表伝言が人工無能によって他のサーバーにばらまかれてしまうのを防ぐ措置である。

コマンド

クライアントがサーバーに送るコマンドには以下のようなものがある。 サーバーは必須コマンドを実装しなければならない。 サーバーは、実装されていないコマンドあるいは解釈・実行できないコマンドを受理した場合、クライアントに対して#形式でエラーを通知する。

名称 形式サポート[1.0]正式ログイン前の
使用可否
ヘルプ /?必須
利用者一覧 /w一部必須
バックログ /r一部必須可(一部不可)
ハンドル設定 /h必須
電報 /p必須不可
エスケープ //必須
ログアウト /q必須
ログアウト /lオプション
ステータス設定 /sオプション不可
表伝言 >>オプション不可
裏伝言 /mオプション不可
伝言受取人一覧 /mlオプション不可
アナウンス /aオプション不可
アナウンス一覧 /alオプション不可
[1.0]ネゴシエーション /x必須

コマンドの書式と機能を以下に示す。

{コマンド文字} ::= '/'
{伝言記号} ::= '>' '>' | {代替伝言記号}
{空白} ::= ' ' | TAB | {代替空白文字}
{ハンドル区切り} ::= ',' | {代替ハンドル区切り}
[0.9] {EOL} ::= CR LF | LF 
[1.0] {EOL} ::= CR LF | LF | CR | CR NUL

「代替」とあるものは、ロケール依存の文字(2バイト文字など)を使用することを想定したものである。

ヘルプコマンド

{ヘルプコマンド} ::= {コマンド文字} '?' {EOL}

使用できるコマンドの一覧と簡単な説明を要求する。 応答は#形式で得られる。書式はサーバーの実装依存である。 サーバー実行中に変化する情報を含めるべきではない。

利用者一覧コマンド

{利用者一覧コマンド} ::= {コマンド文字} 'w' [ 'a' | 'w' | 'o' ] {EOL}

現在ログインしている全クライアントの情報を要求する。 応答の書式はサーバーの実装依存である。 応答には各クライアントのハンドルと番号を含んでいなければならない。 また、サーバーのホスト名とアクセス手段(TCPにおけるポート番号など)、 各クライアントのログイン元ホスト名とステータスを含めることが望ましい。 クライアントのハンドル・ホスト名・ステータスなどが長い場合には、 サーバーは適宜短縮して出力してもよい('a'指定時を除く)。

'o'と'w'のサポートはオプションである。 'a'と無指定のサポートは必須である。

バックログコマンド

{バックログコマンド} ::= {コマンド文字} 'r' [ 'a' | 'n' | [ {空白}... ] {行数} ] {EOL}

行数指定時は、ログの最後の指定行数分を要求する。 'a'指定時は、その日の全ログを要求する。 'n'指定時は、前回ログアウト時以降のログを要求する。 どれも指定されていない場合は、サーバーの実装に依存する特定の行数を指定したものとみなす。 バックログの前後には##形式のマーカーがつく。

バックログ送信中にログが増加した場合、サーバーは増加分をバックログ末尾に含めて送信してもよい。 ただし、そのいかんにかかわらず、終了マーカーの後に増加分を送信しなければならない。

サーバーはバックログ送信中にログ以外の情報(他のコマンドへの応答、 到着電報など)を送信してはならない。

'n'のサポートはオプションである。それ以外のサポートは必須である。

[1.0]仮ログイン中は'n'は使用できない。

ハンドル設定コマンド

[0.9] {ハンドル設定コマンド} ::= {コマンド文字} 'h' {ハンドル} {EOL}
[1.0] {ハンドル設定コマンド} ::= {コマンド文字} 'h' {空白} {ハンドル} {EOL}

ハンドルを設定する。ハンドルの前後の空白はサーバーによって削除される。 サーバーは、新ハンドルを設定後、伝言の再生を行う。

[1.0]仮ログイン中にこのコマンドを実行すると、正式ログインする。

電報コマンド

[0.9] {電報コマンド} ::= {コマンド文字} 'p' [ {空白}... ] {利用者番号} [ {空白} ] [ {本文} ] {EOL}
[1.0] {電報コマンド} ::= {コマンド文字} 'p' [ {空白}... ] {利用者番号} {空白} [ {本文} ] {EOL}

指定のクライアントに電報を送る。 サーバーは発信者には#>形式で受信者と本文を出力し、 受信者には#<形式で発信者と本文を出力する。 利用者番号0は発信者自身とする。

[0.9]本文がない場合、このコマンドは無視される。 したがって空の電報が送られることはない。 またその際サーバーはエラーを通知しない。

[1.0]本文がない場合、空の電報が送られる。

エスケープコマンド

{エスケープコマンド} ::= {コマンド文字} {コマンド文字} [ {本文} ] {EOL}

コマンド文字で始まる発言をする。

[1.0]仮ログイン中に使用した場合、コマンド文字で始まるハンドルを名乗ったものとみなされる。

ログアウトコマンド

{ログアウトコマンド} ::= {コマンド文字} 'q' {EOL} | {コマンド文字} 'l' {EOL}

ログアウトする。 サーバーは他のクライアントに対してログアウトを通知する。

ステータス設定コマンド

[0.9] {ステータス設定コマンド} ::= {コマンド文字} 's' [ {空白} {ステータス} ] {EOL}
[1.0] {ステータス設定コマンド} ::= {コマンド文字} 's' {空白} [ {ステータス} ] {EOL}

ステータスの設定・変更・取り消しを行う。

表伝言

{本文} {伝言記号} {ハンドル} [ {ハンドル区切り} {ハンドル} ]... {EOL}

表伝言を送る。各ハンドルの前後の空白はサーバーによって捨てられる。 サーバーは本文を表伝言として蓄積する。 サーバーは本文以降行末までを発言として蓄積・送信する。 さらに、表伝言を受理した旨を発言または#形式で送信してもよい。

これは発言でありコマンドではないが、便宜上ここで解説する。

裏伝言コマンド

{裏伝言コマンド} ::= {コマンド文字} 'm' {空白} {本文} {伝言記号} {ハンドル} [ {ハンドル区切り} {ハンドル} ]... {EOL}

裏伝言を送る。各ハンドルの前後の空白はサーバーによって捨てられる。 サーバーは本文を裏伝言として蓄積する。 サーバーは裏伝言を受理したことを示すために本文と受取人を#>形式で送信する。

伝言受取人一覧コマンド

{伝言コマンド} ::= {コマンド文字} 'm' 'l'

サーバーに蓄積されているすべての伝言の受取人のハンドル一覧を要求する。 応答は#形式で得られる。

アナウンスコマンド

[0.9] {アナウンスコマンド} ::= {コマンド文字} 'a' [ {空白} {本文} ] {EOL}
[1.0] {アナウンスコマンド} ::= {コマンド文字} 'a' {空白} [ {本文} ] {EOL}

アナウンスを送るかあるいは取り消す。 アナウンスを送った場合、同名のクライアントが以前送ったアナウンスは上書きされる。

なお、特殊ハンドルallに対する伝言もアナウンスとして処理される。 この場合イベントは送信されない。 また、同名のクライアントが以前送ったアナウンスがあればそれに追加される。

アナウンス一覧コマンド

{アナウンス一覧コマンド} ::= {コマンド文字} 'a' 'l' {EOL}

サーバーに蓄積されているすべてのアナウンスを要求する。 応答は#形式で得られる。

[1.0]ネゴシエーションコマンド

{ネゴシエーションコマンド} ::= {コマンド文字} 'x' {空白} {キーワード} '=' {値}
	[ ',' {キーワード} '=' {値} ]...  {EOL}

クライアントからサーバーに対してネゴシエーションを行う。

内容キーワード
クライアントタイプの宣言typenull, normal, biff, mixed
下り文字コードの宣言downcode*junet*など
上り文字コードの宣言upcode*junet*など

[0.9]副プロトコル

流れ

サーバーは以下のタイミングで副プロトコルによるサーバー情報の提供を行う。

サーバー情報は別途規定する形式で送信する。 クライアントが何かデータを送信するとサーバーは接続を切断する。


セキュリティ

本プロトコルではセキュリティについては考慮していない。 特に、以下の点に注意。


参考文献・関連ソフトウェア


参考: ログ等のフォーマットについて

ここでは、ログ等の推奨フォーマットを解説する。 サーバーの実装の際には、既存のクライアントやツールとの互換性のため、 このフォーマットに従うことが望ましい。 クライアントやツールの実装の際には、このフォーマットを想定してよいが、 可読文の内容に依存することはなるべく避けるべきである。

日時はすべてサーバーのローカル日時である。

ログのフォーマット

発言

(HH:MM:SS)[ハンドル] 発言本文

HH:MM:SSはサーバーが発言を受理した時刻である。 ハンドルは発言したクライアントのハンドルである。

(00:00:00)[八重樫] ほげー

サーバー起動

# 可読文

可読文にはサーバーの名称・実装バージョン・起動時刻を含む。 このイベント行は例外的に#で始まる。

例:

# italk+ ver. 0.90beta3 [COWBERRY] here @ 1998-01-01(Sun) 00:00:00 JST

ログイン・ログアウト・強制切断

([ハンドル@ホスト名] 可読文)

ハンドルはイベントを発生したクライアントのハンドルである。 ホスト名はクライアントのログイン元ホスト名である。 可読文にはイベントの内容とイベント発生時刻を含む。

例:

([八重樫@mech.t.u-tokyo.ac.jp] logged in @ 1998-01-01(Sun) 00:00:00 JST)
([八重樫@mech.t.u-tokyo.ac.jp] logged out @ 1998-01-01(Sun) 00:00:00 JST)
([八重樫@mech.t.u-tokyo.ac.jp] logged out ABNORMALLY @ 1998-01-01(Sun) 00:00:00 JST)

その他のイベント

([ハンドル] 可読文)

ハンドルはイベントを発生したクライアントのハンドルである。 可読文にはイベントの内容とイベント発生時刻を含む。

例:

([八重樫] handle change [ハ重樫] @ 1998-01-01(Sun) 00:00:00 JST)
([八重樫] status changed <よー> @ 1998-01-01(Sun) 00:00:00 JST)
([八重樫] status cancelled @ 1998-01-01(Sun) 00:00:00 JST)
([八重樫] announced "よー" @ 1998-01-01(Sun) 00:00:00 JST)
([八重樫] canceled announcement @ 1998-01-01(Sun) 00:00:00 JST)

バックログのフォーマット

## __ BACK LOG START _____________________
    :
バックログ
    :
## -- BACK LOG END ----------------------- 可読文

終了マーカーに可読文がある場合、バックログの行数が含まれる。 行数にはマーカーを含まない。

例:

## __ BACK LOG START _____________________
(00:00:00)[八重樫] ほげー
## -- BACK LOG END ----------------------- (1 lines)

電報のフォーマット

送信側

#> 可読文 (利用者番号) [ハンドル] 可読文
#> 電報本文

利用者番号は受信クライアントの番号である。 ハンドルは受信クライアントのハンドルである。 可読文には電報受理時刻を含む。

例:

#> Message to (0001) [Puppet] @ 1998-01-01(Sun) 00:00:00 JST
#> /q

受信側

#< 可読文 (利用者番号) [ハンドル] 可読文
#< 電報本文

利用者番号は送信クライアントの番号である。 ハンドルは送信クライアントのハンドルである。 可読文には電報受理時刻を含む。

例:

#< Message from (0001) [Puppet] @ 1998-01-01(Sun) 00:00:00 JST
#< :P

参考: 実装の手引

[1.0]ビフクライアントのプロトコルの例

http://www.st.rim.or.jp/%7Elef/italk/files/new12344_0929.txt
以下のように読み替えること。 「旧12344」→「バージョン0.9の副プロトコル」、 「新12344」→「バージョン1.0」、 「12344」→「12345」 また、"type=mixed"と"#! disconnect="が増えていることに注意。
http://www.is.s.u-tokyo.ac.jp/~oiwa/temp/12344.html

解説(rationale)

従来アイトークについては明文化された仕様書がなく、 唯一のサーバーの実装であるitalk+(〜0.8x)の挙動が事実上の仕様であった。 しかし、これでは仕様と実装依存の区別が難しく、 クライアントがサーバーの実装に過度に依存しがちで、 サーバーの仕様変更が制約を受けたりクライアントと齟齬をきたしたりする例があった。 また、サーバー情報のフォーマットのように、 明らかに仕様としての性格をもつ部分についても、厳密な定義が曖昧なままであった。 本仕様書はそのような問題を解消するために編纂された。

仕様の策定にあたっては、以下のような点に留意した。

  1. italk+の既存バージョン(〜0.8x)の仕様を明文化すること。
  2. italk+の将来のバージョンや、他のサーバー・クライアントの実装の指針となること。

すなわち1.は記述的仕様、2.は規範的仕様を要求している。 両者は本質的に相容れない性格のものである。 また、プロトコルは最近仕様が大幅に拡張されたが、 現在稼働しているサーバーはほぼすべて旧仕様に基づくものであり、 新旧両方の仕様が必要である。

このような状況をふまえて、 プロトコル仕様も0.9と1.0の2バージョンに分けることにした。 0.9は上記1.の、1.0は上記2.の要求に応えるものである。 ただし、0.9においてitalk+の実装・挙動をことごとく仕様として記述すると、 仕様が肥大化するだけでなくサーバーの実装の自由度を制限するため、 1.0における仕様と実装依存の妥当な切り分けと想定されるものを 0.9においても準用することとした。 実装依存とされた部分のうち、既存のクライアントとの互換性を保つために 明文化しておくことが望ましいものについては、参考規定で触れている。

1.0では0.9から以下のような点が変更されている。

これらの変更にあたっては、0.9との互換性を保ちながら拡張性をもたせることを旨としたが、 副プロトコルの統合など大きく変更された部分もある。

今後新たにサーバー・クライアント・その他ツールなどを実装する場合は、 1.0に適合することを強く推奨する。 また、クライアント(とくにビフクライアント)を実装する場合は、 0.9にも対応することが望ましい。