Inside.
用語定義
この文書中では、本サイトで配布しているWindows用の"SSTP Bottle Client (SstpBottle.exe)"(アプリケーション名)と、一般的にボトルサーバに接続するためのソフト(互換ソフト)を区別するため、前者を「SSTP
Bottle Client」と表記し、後者を「ボトルクライアント」とカタカナ表記します。
また、SSTP Bottleサービスの物理的なサーバマシン(ハードウェア)を「ボトルサーバ」とカタカナ表記し、その中で動いているSLPPサーバデーモン(ソフトウェア名)は「SLPP
Server」と表記します(一般的に「ボトルサーバソフト」と言う場合には、このSLPP Serverを指します)。
- SLPP
- SSTP Local Proxy Protocol。LPモードを実現するためのプロトコル。簡単なSLPP 1.0(現在停止)とHTTP互換のSLPP 2.0(現行)がある。SLPP1.1は廃止。
- SPCP
- SSTP Proxy Control Protocol。bottle.mikage.to内でCGIとSLPP Serverがローカルに通信するためのプロトコル。
- SSTP
- Sakura Script Transfer Protocol。ポート11000もしくは9801を使用するもの。
- SLPPクライアント
- SLPP Serverに接続を行うためのソフト。つまりボトルクライアントはSLPPクライアントである。
SLPP2.0より、SLPPはHTTP互換であるため、SLPPクライアントといった時点でHTTP Clientである。 - SSTPサーバ
- 「何か(仮)」や「SSP」「CROW」など、SSTPを受信することができるソフトウェア。
- CGI
- SLPPはメッセージなどのリアルタイム受信専用であり、Bottle Clientからのコマンド送信などは、CGIを経由して行われる。この文書中の「CGI」は、具体的にはhttp://bottle.mikage.to/bottle2.cgiを指す物とする。
- SLPP Server(旧称:SSTP Proxy)
- bottle.mikage.toサーバ上に常駐しているソフト。一般的に言われているボトルサーバソフトウェア。全IPアドレスを管理し、「SLPPサーバ」「SPCPサーバ」の1台2役を受け持つ。"SSTP Proxy"という名称は、直接SSTP通信を行っていない以上不適切であるため廃止。
- ボトルクライアント
- 「SLPP2.0クライアント」「SSTPクライアント」の2つの役目を果たすソフト。つまりボトルサーバからメッセージを受信してSSTPサーバに転送するソフトウェア。
- メッセージ Message
- SSTP Bottleにおいて特に断りなく「メッセージ」という単語を使った場合は、ボトルクライアントやブラウザからユーザによって作成・投稿された、Sakura Script文、またはそれを含んだSSTPリクエスト文を指す。いわゆる「ボトル」と同義語と考えて差し支えない。
- 接続 Connect
- 単に、TCP/IPのコネクションを確立すること、またはその確立されたコネクションのこと。
- SLPP2.0に接続
- このように使った場合、これは、単純にSLPP2.0サーバにTCP/IPコネクションを確立したことを示す。
- SLPP2.0と接続を確立
- これは、SLPP2.0サーバから、準備完了のメッセージ(HTTP OK)を受信したことを示す。
- 切断 Disconnect
- 接続の反対語。TCP/IPのコネクションを終了すること。
- 参加 Join
- チャンネルのメッセージを受信できる状態になることを、チャンネルに参加する、と呼ぶ。
- 脱退 Leave
- チャンネルからのメッセージを受信しない状態にすることを、チャンネルから脱退する、と呼ぶ。
- 投稿 Post
- メッセージをCGIに送信して配信させること。いわゆる「ボトルを送信する」こと。
- 配信 Broadcast
- SLPP Serverがメッセージをユーザ側マシンまで送信すること。いわゆる「ボトルが運ばれてくる」こと。
- 転送 Dispatch
- SLPP Clientが、配信されたメッセージを、ローカルマシンの適切なSSTPサーバに送信すること。
- 再送 Resend
- SSTPサーバのConflict時などに、SSTPクライアントが同じメッセージを再度SSTPで送信すること。ボトルクライアント固有の機能であるので、この文章中では解説しない。
- メッセージID (MID)
- SLPP ServerがSLPP2.0のメッセージ配信の際に全てのメッセージに付与する固有の文字列。
- ロングユーザID (LUID)
- SLPP Serverが要求に応じてランダムに生成し、CGI経由で渡されるユーザ固有の文字列。HTTPによるCGI接続とSLPPによる接続を同期させるために必須である。接続のためのパスワードのような存在であり、第三者には非公開でなければならない。
- ユーザID (UID)
- SLPP ServerがLUIDとセットで生成する文字列。内部用でありアルゴリズムは企業秘密。公開しても、なりすまし等は行えないのでシステム上の差し支えはないが、個人特定が可能であるため、現在公開されていない。
概要
2つの接続
- [Client→SLPP Server]SLPP
Clientは、メッセージの受信や、その他の情報のリアルタイム受信用として、bottle.mikage.to:9871
を使用します。これは以下に述べるSLPP2.0プロトコルを使用しますが、これはHTTPと互換のプロトコルです。
したがって、SLPP Clientから情報を流せるのは最初の1度のみです。(POSTとして流す) - [Client→CGI]というわけで、接続後にSLPP ClientからBottleサーバ側に情報を流したい場合には、通常のHTTPプロトコルを利用して、 http://bottle.mikage.to/bottle2.cgi にPOSTメソッドでデータを流します。
- これらの、SLPP ClientとBottleサーバ側の2種類の接続を同定するために、LUIDと呼ばれるIDが必要です。LUIDは、Client→CGI 接続で getNewId コマンドを発行することで取得します。
- すべてのデータはShift-JISで流れます。また改行はCR+LFです。
例
ユーザからメッセージの投稿があった場合、
- 標準のHTTPを利用してCGIが起動され、メッセージが送信されます
- CGIはボトルサーバ内部でSPCP通信により、SLPP Serverプログラムにチャンネル名とメッセージを送ります
- SLPP Serverは、自身にSLPP通信しているすべてのボトルクライアントプログラムに、(チャンネル名などに応じて)メッセージを配信します。
- ボトルクライアントはSLPP通信からメッセージを受信し、それをSSTPを使ってSSTPサーバに転送します。
- SSTPサーバで、メッセージが再生されます。
Client → SLPP Server 接続(SLPP2.0)
接続開始
bottle.mikage.to:9871に接続して、
POST /#13#10
#13#10
LUID#13#10
と送信してください。つまり、SLPP Server http://bottle.mikage.to:9871/ に対してLUIDをポストしてください。
[LUID]は、先にCGIから取得した80文字あまりの文字列で、特にURLエンコードする必要もないよう、[a-zA-Z0-9\.]の範囲の文字列を使用しています。
受信
LUIDの認証に成功すれば、
HTTP/1.0 200 OK#13#10
Content-Type: text/plain; charset=Shift_JIS#13#10
Pragma: no-cache#13#10
Cache-Control: no-cache#13#10
#13#10
が、SLPP Serverから返ります。これをもって、SLPP2.0で接続を確立した、とみなします。
この後は、1行以上の空行(改行コードは #13#10 です)に区切られて、さまざまなコマンドが送信されてきます。
それぞれのコマンドは、1行目がコマンドの種類であり、その後さまざまなパラメータが返ります。
パラメータは、SSTPで使われているのと同じ、
Key: Value#13#10
形式です。(RegExpで m/^(.+?)\:\s+(.+)$/
)
互換性のため、行内にコロンが入っていない行が流れることがありますが、そういった行は基本的に無視するようにしてください(SSTPとしてそのまま転送しても動きません)。
順序依存性はないように実装してください。(将来も現在と同じ順番でパラメータが流れれてくるとは限りません)
同名のキーが、リストとして複数流れることはあります。(Aというパラメータが複数流れることがある)
broadcastMessage コマンド
送信されたBottle本体が流れます。
- SenderUID:
- 送信者のUIDです。現在は個人特定防止のため、この情報自体が省略されています。
- MID:
- メッセージに付与されたIDで、すべてのメッセージでユニークです。
- Script:
- メッセージのスクリプトです。
- IfGhost: [optional]
- IfGhost付きで流れたメッセージの時に、そのゴースト名が付加されます。
が、keroname側の名前が指定されていませんので、これをこのままSSTPサーバのIfGhostとして流しても動作しません。 - Channel:
- 送信されたチャンネルです。
forceBroadcastMessage コマンド
チャンネルに関係なく、お知らせ用に一斉同報メッセージを流します。
ScriptとDialogMessageは、片方のみ、または両方のみが流れてきます。ないはずですが、もし両方とも欠けていた場合はきちんと無視してください。
- SenderUID:
- 送信者のUIDです。この場合の「送信者」は普通のボトルユーザではない管理用のIDです。基本的に無視して差し支えありません。
- MID:
- メッセージに付与されたID。
- Script: [optional]
- 一斉同報のためのスクリプトです。SSTP Bottleサービス管理者からの重要なメッセージが含まれています。SSTPサーバに転送してください。
- DialogMessage: [optional]
- 一斉同報のためのメッセージです。SSTP Bottleサービス管理者からの重要なメッセージが含まれています。ダイアログを表示するなりして対処してください。
allUsers コマンド
SLPP2.0でSLPP Serverに接続している全接続の数を返します。
なお、同じLUIDで同時にSLPP Serverには1つの接続しか張れないので、ここで返る数 = LUID の数、となります。
これは、接続人数が変更されるごとに頻繁に流れますので、全人数のリアルタイム監視が可能です。
- Num:
- 全接続人数です。
channelUsers コマンド
登録されているチャンネルの数だけ流れます。
なお、同じLUIDで同時にSLPP Serverには1つの接続しか張れないので、ここで返る数 = LUID の数、となります。
これは、接続人数が変更されるごとに頻繁に流れますので、人数のリアルタイム監視が可能です。
- Channel:
- Numパラメータで人数が流れるチャンネルです。
- Num:
- 人数です。
channelList コマンド
現在自分が登録しているチャンネルのリストを返します。
これは、CGI側から要求することで、SLPP Server側から返ってきます。
- Num:
- 登録されたチャンネルの数です。
- Entry: [multiple, optional]
チャンネル名 (人数)
の形式で、登録されているチャンネルとその人数が返ります。チャンネルに登録されていない場合は何も返りません。
broadcastInformation コマンド
特定のチャンネルを受信している人に、付加的な情報を送信します。
定義されているのは以下のヘッダだけで、その他のヘッダについては定義されていませんが、Type:ヘッダの内容に応じて戻ってきます。
- Channel:
- 情報送信先のチャンネルです。
- Type:
- 情報の種類です。
forceBroadcastInformation コマンド
すべての接続ユーザに、付加的な情報を送信します。
定義されているのは以下のヘッダだけで、その他のヘッダについては定義されていませんが、Type:ヘッダの内容に応じて戻ってきます。
- Type:
- 情報の種類です。
forceBroadcastInformation コマンド - Type: Vote
forceBroadcastInformation Type: Vote では、メッセージの投票数に関する情報が流れます。
追加されたヘッダは以下の通りです。
- MID:
- 投票数に変更があったメッセージID。
- Num:
- 投票数。
forceBroadcastInformation コマンド - Type: Agree
forceBroadcastInformation Type: Agree では、メッセージの同意数に関する情報が流れます。
追加されたヘッダは以下の通りです。
- MID:
- 同意数に変更があったメッセージID。
- Num:
- 同意数。
closeChannel コマンド
closeChannelは強制的にチャンネルを閉鎖することを通知します。
SLPPクライアントは、そのチャンネルの閉鎖を通知するとともに、それ以降そのチャンネルに投稿しないよう、しかるべき処置を行ってください。その後にそのチャンネルに投稿しようとしても、CGIがエラーを返すでしょう。
- Channel:
- 閉鎖されたチャンネルの名前。
Client → CGI 接続(HTTP1.1)
接続
http://bottle.mikage.to/bottle2.cgi に対してPOSTメソッドでリクエストを発行してください。
リクエストは、WWWブラウザがフォームから発行する形式ではなくて、Key: Value
形式です。
共通のリクエストパラメータ
すべてのリクエストは、共通に以下のパラメータを発行する必要があります。
- Command:
- CGIに発行するリクエストコマンド名です。
- Agent:
- SLPP Clientの名前です。例えば、「SSTP Bottle Client ver 2.0」のような文字列を渡してください。
すべてのリクエストで必ず発行してください。
共通の戻り値
すべてのコマンドは、共通に以下の戻り値を返します。
- Command:
- CGIに発行されたコマンドです。これをはじめ、戻り値の処理に必要な情報は戻り値の中に含まれるはずですので、SLPP ClientはCGIに発行したコマンドをいちいち記憶する必要はなく、また、必要があれば同時に複数接続で複数のコマンドを発行しつつ、戻り値は一元処理することも可能です。
- Result:
- コマンドが成功した場合は、
OK
が、失敗した場合はErr
が返ります。 - ExtraMessage: [optional]
- コマンドが失敗した場合にのみ、失敗の理由などのメッセージが日本語で流れます。
SLPP Clientはこのメッセージをしかるべき方法でユーザに通知して、コマンドが失敗したことを伝えてください。
Result: Err にもかかわらず、このメッセージが省略される場合もあります。(ボトルサーバが何らかのエラーを返しました、とでも表示してください)
getNewId リクエスト
新規にLUIDを取得します。
SLPP2.0でSLPP Serverに接続する前に、新規にLUIDを取得する必要があります。
接続のたびに新しいIDを取得するような実装はしないでください。いったん取得したLUIDは保存するようにお願いします。
追加されたリクエストパラメータはありません。追加されたレスポンスは以下の通り。
- NewID:
- 新規に発行されたLUIDを返します。
sendBroadcast リクエスト
メッセージを送信します。
- LUID:
- LUIDを指定します。
- Channel:
- チャンネルを指定します。
- Talk:
- 送信するスクリプトを指定します。
- Ghost: [optional]
- IfGhostを指定します。本体名だけ渡してください。(keroname不要)
Ghostが渡されなければ「チャンネル指定ゴーストを使ってください」という意味になります。
追加されたレスポンスは以下の通り。
- Num:
- 成功した場合に、送信された人数を返します。
- Channel:
- 成功した場合に、送信されたチャンネルを返します。
voteMessage リクエスト
メッセージに投票します。
- LUID:
- LUIDを指定します。
- MID:
- メッセージIDを指定します。
- VoteType:
- 投票の種類を指定します。"Vote"または"Agree"のいずれかの文字列を返します。
追加されたレスポンスは以下の通り。二重投票の場合にはErrが返りますので注意してください。
- Votes:
- 成功した場合に、新しい投票数(または同意数)を返します。
getChannels リクエスト
現在開設されているチャンネルのリストを返します。
- LUID:
- LUIDを指定します。
追加されたレスポンスは以下の通り。
- Count:
- 成功すれば、開設されているチャンネルの数を返します。
以下のパラメータの??の部分は、このCountの数字を上限とする1以上の整数の文字列表現です。 - CH??_name:
- チャンネルの名前です。
- CH??_ghost:
- チャンネル推奨ゴーストです。keroname側は含まれません。
- CH??_info:
- チャンネルの説明です。
- CH??_warnpost:
- これが1になっている場合は、投稿の前に確認メッセージを表示する、という意味で導入されたヘッダですが、ボトルクライアントはこの情報を利用しても利用しなくても構いません。
- CH??_nopost:
- これが1になっている場合は、このチャンネルが受信専用チャンネルのため、メッセージを送信できないようにしてください。
- CH??_count:
- このリクエストが発行されたときのそのチャンネルの登録人数です。
setChannels リクエスト
登録するチャンネルを指定・変更します。
常に、参加したいチャンネル全体のリストを渡してください。ここで渡されなかったチャンネルは登録が解除されます。
- LUID:
- LUIDを指定します。
- Num:
- 登録するチャンネルの合計数を指定します。全チャンネルから抜けたい場合は0を渡します。
- Entry: [multiple]
- チャンネル名を指定します。1つのパラメータ(行)に1つのチャンネルを渡す形で、このパラメータはNum回(0回以上)繰り返して書いてください。
追加されたレスポンスはありません。(単純にOKまたはErrのみ返る)
このリクエストコマンドが実行されると、SLPP Server側からChannelListコマンドが流れますので、SLPP
Clientはこちらに応答することで、このリクエストの成功を確認してください。
SLPP Client要件
SLPP Clientに必要とされる要件は以下のとおり。
投稿を行えるようにする場合の制限は厳しいですが…
必須要件
- bottle.mikage.to:9871への接続
- http://bottle.mikage.to/bottle2.cgiへのHTTP接続
- 以下のSLPP2.0コマンドの解釈
- forcebroadcastMessage
- broadcastMessage
- closeChannel
- channelList
- 転送(Dispatch)を行う場合は、
- \URLタグの正確な変換
- 投稿(Post)補助を行う場合は、
- 禁止タグチェック。SSTP Bottleで使用許可されていないタグを投稿不可能にすること。
要望要件
- HTTP Proxyを通したbottle.mikage.to:9871への接続
- 以下のSLPP2.0コマンドの解釈
- allUsers
- channelUsers
- sendUnicast
- 転送(Dispatch)を行う場合は、
- Conflict時のメッセージ再送
- DirectSSTP等による、ゴーストが指定された場合の振り分け実装
- 投稿時と同レベルの禁止タグチェック