birdUDP Reflector 改め DP Reflector

UDP Reflector 改め DP Reflector

結局、再送処理等に関していろいろ考えているのが面倒になってきたので1、UDP/TCP を混在させて利用可能な形にすることにしました。クライアントはアプリケーション側の要求やいろいろな制約を鑑みてどちらのプロトコルでも好きなように利用できます。DP Reflector の DP は Dual Protocol の DP なのだ(笑。
つまり、完全性や順序性が欲しいアプリケーション (または個々の通信要求) は TCP を使えばいいし、そういったものはいらないのでもっと性能が欲しい場合は UDP を使えば良いと。DP Reflector 側では UDP 時には完全性や順序性を一切保証しませんので、もし UDP を使いつつそういったものが (多少なりとも) 欲しい場合はアプリケーションレイヤーで作りこむ必要があります。
TCP でのやりとりのために追加になったコードと、再送処理が必要なくなったために削除したコードの分量はほとんど同じくらいか、多少前者の方が多いかな、という程度。UDP 版、TCP 版のテストクライアントも含めてありますが、かなりシンプルになったように思うのですがどうでしょうか?
再送処理がなくなった関係で、パケットフォーマットが少し変更されています (シーケンス番号フィールドがなくなった)。また、TCP ストリーム上へのパケットの乗せ方の仕様も追加になりました。さらにチャネルに参加しているクライアントのリストを得る LIST コマンドも追加になっています。
今回も www.digitune.org の 15315 番ポート (TCP/UDP とも) で動かしておきますので、テストにでも使ってくれい>かぴのすけ。
ナチュラルに inner-inner-class を使ってしまった…。うひょー。

コメント

かぴのすけ (Thu, 08 Jul 2004 22:11:28)
あーくそねむー。

> サーバ側、クライアント側でやるべきことに差はない。

ありまくると思うが。低レベルの通信部分だけ見れば差はない。

> 「カイレラ」ってなんだ? Internet 環境では数百 ms の遅延くらいは結構普通らしいから、
> 一秒間に数回以上のレスポンスを望むのは難しいらしーぞ。逆に言えば、そのくらいのディ
> レイがあっても破綻がないようなロジックを考える必要がある、と。

カイワレみたいなやつ。辛い。
平均 ping 値 50 ms 前後の環境を想定してるんで、実はツネんちあたりだと
物理的に問題がある。

>「シンクロ専門オブジェクトでタイミングを明示的に」の意味が良く分からないんだけど

別にシンクロ用オブジェクトはいらんのだが、パケ待ちとか絶対安全なところだけ
割り込めるよーにしれってこった。ちうか、ジャバて「○秒後に割り込み」とか便
利な機能がないんかい。

> 「タイミングによって例外が出て」こないようにするためにきめ細かい同期処理を行って
> いるわけで。

今回はなんか異様に気ぃ使ってシンクロしているっぽいすな。それでも穴があるけど。

> …とゆーわけで上にも書いたが再送処理は全部削除しちゃいました。
> TCP ならかぴのすけのサーバと大差ないから、クライアントも簡単に作れることでしょう

うーむ。つまんねーサーバになってきたな。
量子通信とかもっと画期的新機能を盛り込んでくれ。特にスコアランキング機能希望。

TCPでもかなりやってることが違うからクラ作るのは難しくもないけど簡単というほどでもない。むしろ不親切。カピサーバを15315番で動かしてくれた方がうれしいかも。

ゲムーはなにを用意しよーかなー。とりあえずアレかアレだな。
Digitune (Thu, 08 Jul 2004 23:23:34)
> 低レベルの通信部分だけ見れば差はない。

そこ以外のどこの話をしていたというのじゃ。

> 平均 ping 値 50 ms 前後の環境を想定してるんで、

それって LAN じゃん。LAN は LAN でも無線 LAN だったりするとそれだけでも厳しいぞ。そんな適応性のないプログラムはつまんないなー。

> パケ待ちとか絶対安全なところだけ
> 割り込めるよーにしれってこった。ちうか、ジャバて「○秒後に割り込み」とか便
> 利な機能がないんかい。

うーんやっぱり分からん。IO 待ちしてる時以外はオールロック (つまり常に動いている Thread は1本)、ってこと?thread 使わない Unix プロセスみたいな感じか。

Java も 1.4 になってから結構その辺は融通が効くようになってきたと聞くが、俺はまだよく知らん。普通に thread ぶん回す (せいぜい thread pool を使う) んでも大抵のことは間に合っちゃうからなー。

> 今回はなんか異様に気ぃ使ってシンクロしているっぽいすな。それでも穴があるけど。

とゆーかあのくらいは普通。昔の Java だとシステムライブラリ自体が安全側に振ってあって、例えば Vector や Hashtable はデフォルト同期ポリシーだったわけだが、Java2 以降の Collection Framework においてはデフォルト非同期に変更になった。ので、最近はああいう具合になる。いろんなところからアクセスされるメンバにはあえて昔の Hashtable とかを使う、ってのも楽でいいんだけどね。とはいえ Enumeration/Iterator を使おうと思うとやっぱりインスタンスの外部に同期セクションを作らなきゃいけないんで、そんなら全部それでいいじゃん、ということだ。

今回はもともと UDP only でアクティブスレッド2本だけだったからどちらかと言えば気合いが抜けてる方だと思うぞ。なので穴もあろう。ってどこよ?

> うーむ。つまんねーサーバになってきたな。
> 量子通信とかもっと画期的新機能を盛り込んでくれ。特にスコアランキング機能希望。

サーバが面白くてどーするよ。面白いのはあくまでもクライアント側でしょ。サーバは黙々と働き続ければよろし。

> TCPでもかなりやってることが違うからクラ作るのは難しくもないけど簡単というほどでもない。むしろ不親切。

どこが不親切だとゆーのかね。必要最低限の機能はすっぽり盛り込まれておるであろうよ。使い方もチョー簡単だし。

サーバとゆーのは一人で多くのクライアントをサーブしなきゃいけない立場上、「自分で保持すべきデータ」と「保持すべきでないデータ」にはかなり気をつかって作られる必要がある。面倒見なくてよいデータはトコトン無視するのが正しい姿勢。そーでなくちゃスケーラビリティなんて絶対出ない。本質的にクライアント側で保持出来る/保持すれば事足りるデータなら、全部クライアント側に持たせるくらいのポリシーが正解。

そういう意味では socket 一つ一つに thread 張りつかせてる今回のプログラムはかなり手抜きなわけだが、まぁそんなのは瑣末事だ。やろうと思えばいつでも nio+threadpool 実装に切替えられるわけで。
Digitune (Thu, 08 Jul 2004 23:28:31)
> 特にスコアランキング機能希望。

こういうリアルタイム性をまったく持たせる必要がない機能は今回のサーバに同居させるべきじゃない。最近はこの手のデータをやりとりする場合は大抵 HTTP (Web Server) を使うようですな。
スコア登録 cgi とマシンリーダブルな形 (まぁ XML とか) でのスコア送信 cgi を用意すればそれで十分。欲しければそれも設置しますぜ。
SAK (Fri, 09 Jul 2004 18:24:50)
せっかくなので、UDP hole punching機能もきぼんぬ。
コレが使えるなら、UDPパケットなら、Reflectionさせるより性能は遙かに有利だろ。
TCPはダメだが。
Digitune (Fri, 09 Jul 2004 19:04:27)
ふむ。UDP hole punching を実現するには、基本的にはサーバから見えてるクライアントの IP アドレス、ポート番号の組を教えてあげる機能があれば大丈夫なようですな (後はクライアント側の頑張り次第だ)。

しかし、「同じソースアドレス、ポートから出てきたパケットは同じ外部ポートにアサインする」NAT box ってそんなに一般的なのかなぁ?UDP だったとしても宛て先 (受取先) の制限がかかっている以上、同じソースポートから送信されたパケットでも宛て先毎に外部ポートを分けるような実装の NAT box も普通にありそうだけど…。

まぁ検討しときます>SAK。
かぴのすけ (Fri, 09 Jul 2004 21:00:32)
へんじなげーよ。

> そこ以外のどこの話をしていたというのじゃ。

低レベル部分クリアしてもいろいろやることが多いだろよクラは。
そこに差がなくても意味なし。

> それって LAN じゃん。

大阪ぐらいまでなら40msでつながるがな。

> やっぱり分からん。

ならいい。

> 気合いが抜けてる方だと思うぞ。

だろうな。

> ってどこよ?

例えばシンクロの外で

if(clients == null)
return null;

とか判定してるような箇所が見られるが、判定抜けた直後にclientsの指すインスタンスがなくなっちまった場合など。

> サーバが面白くてどーするよ。

面白いサーバじゃないと面白くないだろ。ソフトウェアイーサに対抗してソフトウェア量子通信機能を付けれ。

> どこが不親切だとゆーのかね。

例えばチャネル番号じゃなくてチャネル名で登録参照したいわけだが、できない。and so on.

> サーバとゆーのは

なんか聞いてないのに語りだしたぞ。○ただなぁ。
人数制限付ければ処理負荷なんざ無問題〜。

> 最近はこの手のデータをやりとりする場合は大抵 HTTP (Web Server) を使うようですな。

うーむ。PHPが使いたいからか?。安直。

別にスコアごときリアルタイムなサーバに同居させてもいーんじゃねーかと思うがね。
どーせ ad hoc サーバだし。かたいこというなよと。
SAK (Fri, 09 Jul 2004 22:54:31)
>同じソースアドレス、ポートから出てきたパケットは同じ外部ポートにアサインする」NAT box ってそんなに一般的なのかなぁ?
知らんヽ(´ー`)ノ
だが、宛て先(受取先)の制限付けちまうと、だだでさえ貴重なNAPTテーブルを余計に消費するので、安NAT箱なら制限を付けないってのは合理的な設計だろう。

まぁ最大の目的は、UDP hole punchingが実際に動いているところ見たこと無いので、 見たかっただけだが。

>やろうと思えばいつでも nio+threadpool 実装に切替えられるわけで。
C言語での実装きぼんぬ。Kernel2.6の爆速pollの出番ですよ(*´Д`)ハァハァ
Digitune (Fri, 09 Jul 2004 23:13:00)
> 例えばシンクロの外で
>
> if(clients == null)
> return null;
>
> とか判定してるような箇所が見られるが、判定抜けた直後にclientsの指すインスタンスがなくなっちまった場合など。

C++ かなんかと勘違いしてるようだが、Java では GC されない限りインスタンスが消滅することはない。そして、リファレンスが存在する限り GC 対象にはならない。よって、同期化されてようがいまいが一旦リファレンスを取得したインスタンスがいつのまにか消えてしまうことはありえない。ソフト・リファレンスだったりすると話は別だが。

> 例えばチャネル番号じゃなくてチャネル名で登録参照したいわけだが、できない。and so on.

いわゆる ID として直接名前 (文字列) を使うのは非効率だろう。どこかに ID と名前のマッチングテーブルが存在すればいいわけで、リアルタイム性が必要ないそういう機能は全部外だしじゃー。

> 人数制限付ければ処理負荷なんざ無問題〜。

実装上の都合でキャパシティが決められちゃってるシステムって最低最悪だと思うんだが。例えば昔の FAT の 8.3 とか。時代を考えれば仕方のない部分もあったと思うが、Unix 以降のシステムではそういう理不尽な制限は可能なかぎり設けない、というのが常識だろう。

> うーむ。PHPが使いたいからか?。安直。

それをいうなら JSP とか EJB というのでわなかろうか。PHP は使ったことない。

> 別にスコアごときリアルタイムなサーバに同居させてもいーんじゃねーかと思うがね。
> どーせ ad hoc サーバだし。かたいこというなよと。

ならば、スコア集計専用クライアントを常駐させることにしてそいつと通信させる。そうしとけば必要なくなり次第単純に止めればいいし、別アプリ用の別ロジックで集計するような仕組みも簡単に同居させられる。モノリシックにサーバにどんどん機能を追加していってしまうのはよくないよ。そういうことするから盲腸みたいな機能ばっかりどんどん増えて、Windows みたいになっちゃうのだ。
Digitune (Fri, 09 Jul 2004 23:22:15)
> だが、宛て先(受取先)の制限付けちまうと、だだでさえ貴重なNAPTテーブルを余計に消費するので、安NAT箱なら制限を付けないってのは合理的な設計だろう。

俺がこないだまで使ってた CATV 局が使ってた NAT box はそうじゃなかったけどね。宛先違いで別ポートアサインするかどうかまでは分からないけど (単純にアクセスリストライクな実装も考えられる、ということ。ちゅーか UDP でも connect すれば指定した相手以外からのパケットは普通に捨てられるじゃんよ)。

> まぁ最大の目的は、UDP hole punchingが実際に動いているところ見たこと無いので、 見たかっただけだが。

サーバ側はそんなに大変ではないので、別に実装することはやぶさかじゃない。でも問題はクライアント側でしょー。そっちは自分で作るように。

> C言語での実装きぼんぬ。Kernel2.6の爆速pollの出番ですよ(*´Д`)ハァハァ

C で実装するのもまぁ面白そうではあるのだが、いかんせん何かと不自由でのう。年寄りには辛いのじゃよ…ゴホゴホ。
かぴのすけ (Sat, 10 Jul 2004 21:35:42)
試しに引用を女子高生風にしてみた。

> リファレンスを取得したインスタンスがいつのまにか消えてしまうことはありえな〜い

あー、なんかそんなような仕様だったなー。懐かしい思い出だ。

Cleaner 中で rc.close() などと明示的ななんらかのクローズ処理をやら
かしていたりもするよーだが、こういうのの影響で例外が出たりはしないのか。

> どこかに ID と名前のマッチングテーブルが存在すればいい

どこだよ。

> 実装上の都合でキャパシティが決められちゃってるシステムって最低最悪〜

キャパの制限つーものはたいてい実装上の都合なわけだが。

> モノリシックにサーバにどんどん機能を追加していってしまうのはよくないよ

てーか、今の仕様が何もなさ過ぎ。

で、具体的にウインドーズのどの機能が盲腸なんだ?。

盲腸や農家の四男坊なんてのは簡単に切っちまっていいもんじゃないぜ。って誰かゆってた。
Digitune (Sun, 11 Jul 2004 10:34:55)
> 試しに引用を女子高生風にしてみた。

なぜ女子高生風…。

> Cleaner 中で rc.close() などと明示的ななんらかのクローズ処理をやら
> かしていたりもするよーだが、こういうのの影響で例外が出たりはしないのか。

ReflectorClient の内部状態 (保持してる Socket とか) が変化する可能性のある、isOwnPacket と send と close は同期 (synchronized) メソッドなので他のものが実行中はその他の呼出はブロックされる。なので例えば send と close が同時に呼ばれたとしても、send の方が早ければ close がブロックされるし、close の方が早ければ send がブロックされて Socket close され、TCP での送信は出来なくなる (ただしその場合でも UDP では送信されるだろうが、Cleaner により Map から remove された ReflectorClient にはそれ以降到達するパスがなくなるので GC されてジエンドだ)。

> どこだよ。

個々のクライアントが保持しててもいいし、専用の人がいても良い。いろいろなクライアント側の要求仕様によって最適なものをつど選べばよかろう。

> キャパの制限つーものはたいてい実装上の都合なわけだが。

俺が言いたかったのは、各レイヤーのプログラムが、恣意的に制限を導入してしまう、という状況がダサい、ということ。より上位のプログラム (OS とかマシンリソースとか) により必然的に課されるもの以外の制限は可能なかぎりないようにすべきでしょう。

> てーか、今の仕様が何もなさ過ぎ。

基本はこれでいーんだよ。後は個々のクライアント毎にいろんなパーツを考えていくことになる。例えばグループ名が欲しいんならそれをどう実現するのがよいか、またスコア集計したいならどうか、という点だな。

> で、具体的にウインドーズのどの機能が盲腸なんだ?。

いーっぱいあるらしいぞ。聞くところでは、互換性維持のためにアプリケーション名をチェックしてヒープアロケータを切替える、とかやっているらしい。これは元々のコードにバグがあったせいらしいが、まぁその手の話には事欠かないわけだ。

互換性維持自体は大事なことだが、そういう盲腸的なコードをずっと引きまわさなければいけなくなってしまうような元々の仕様の立て方がよくない、ということ。

Apple が Carbon でやったこと (それまでの API を整理して、旧 OS と新 OS で共通に使える Carbon API を提供、それに準拠したプログラムを書けば新 OS での動作も保証してあげたこと) はなかなかうまい手だよな。その上で旧 OS 完全互換環境 (Classic) も用意するがパフォーマンス・安定性的に劣る、となれば、どうしても古いアプリを使い続けなければならないユーザは Classic で救えるし、ベンダーは積極的に Carbon に対応してくれる。Windows もそんな感じにすればいーんだよ。次の Longhorn ではそんな感じになるんだろうか (古いアプリはみんな Virtual PC 内での実行だったりして・笑)。
Digitune (Sun, 11 Jul 2004 10:42:28)
> 個々のクライアントが保持しててもいいし、専用の人がいても良い。

例えば今話題になっていたグループ名ならば、「最初に入室した人が自由に決められる」ならば、クライアント側で保持しておくのが合理的だ。各クライアントは入室前後に「グループ名なにー?」メッセージをブロードキャストすることにし、それに対して返事がなければ自分で決め (または「空室」表示し)、返事があれば以降はそれを利用、ということだな。

// もちろん、同期処理にはそれなりに気をつかう必要がある。
// このへんの通信は TCP を用いる必要があろう。
かぴのすけ (Sun, 11 Jul 2004 19:56:31)
> ジエンドだ

ふーむ。C++だとかなりヤバーな非同期コードも Java だとそうでもないのか。こんなのに慣れると潰しが利かなくなるな。

> 必然的に課されるもの以外の制限は可能なかぎりないようにすべきでしょう。

そりゃ当然だが、例えば今のサーバ(ハード環境含む)が100人同時接続に耐えられるかつーと無理っぽい。なので、人数制限するのは別になし崩し的でもないだろう。

> そういう盲腸的なコードをずっと引きまわさなければいけなくなってしまうような
> 元々の仕様の立て方がよくない

仕様から来ているのか仕様外動作から来ているのかはだいぶ異なるわけだが、その辺ごっちゃになってないか。挙げてる例とか。

まあ仕様そのものがあやふやな部分は割とあるわけだけどもな。そんなのはそのうちなんとかなんだろー。荒削りでもガンガン先に進もうとするMSのやり方はオモロいので嫌いじゃないぜ。もっとカオスれ。

> Apple が Carbon でやったこと

ふつーじゃん。それにそんなスマートな物作りできてるとこなんかほとんどねえよ。傍目にエレガントそうに見えてもたいがい内情はボロボロのドロドロ。

あと、DOS => 3.0 => 95 => NT というかなりドラスティックな流れがあった割には意外とそれほど大きな問題もなくすんなり過ぎ去ったよーな感じがするわけだが。問題にしたがってるだけじゃねーかと。

> グループ名ならば、「最初に入室した人が自由に決められる」ならば、
> クライアント側で保持しておくのが合理的だ

自分が最初かどうかはどこでわかるんだ?。
かぴのすけ (Sun, 11 Jul 2004 23:30:08)
で、

ちょっと実際にテストコード(しかもジャバ。awt の使い方から再勉強だ)で試してみたわけだが。
あからさまにわかったバグはアクセスに関係なく30秒でブッちされるっつーこと。

それもそのはずで、リフサバクライアントクラスの lastAccessTime の値をコンストラクタでセットしたっきり更新しないよーなコードになっておる。

UDPで試してレスポンスは割ともっちゃりしていたわけだが、クラがジャバだったということもあって一概にネット遅延のせいとは言えん感じがした。

にしても、ここのスレッドやたらと長くなったなー。
Digitune (Mon, 12 Jul 2004 09:30:47)
> ふーむ。C++だとかなりヤバーな非同期コードも Java だとそうでもないのか。こんなのに慣れると潰しが利かなくなるな。

逆に言えばそれだけプログラマの負担が減っている、とも言える。良いことだ。

> まあ仕様そのものがあやふやな部分は割とあるわけだけどもな。

そういうことで。他の例としては ActiveDesktop とか。過去鳴り物入りで登場しつつ今は盲腸になり下がってる機能なんて、探せばいくらでも出てきそうだ。

> それほど大きな問題もなく

昨今の「日刊 Windows 不具合通信」のような状況を見てもまだ大きな問題はない、と言えちゃう君は幸せものだ。盲腸のような機能が積もり積もって管理限界を超える複雑さを生み出してしまっていることが諸悪の根源でしょう。大体、IE のセキュリティホール直したらスクロールバーの挙動がバグりました、ってなんだよ。コンポーネント間の依存マップが誰も制御できないカオス状態になっているとしか思えん。

> 自分が最初かどうかはどこでわかるんだ?。

ブロードキャストすれば。うまいことシーケンス組み立てればトランザクション的にその辺を処理することも可能。

> あからさまにわかったバグはアクセスに関係なく30秒でブッちされるっつーこと。
>
> それもそのはずで、リフサバクライアントクラスの lastAccessTime の値をコンストラクタでセットしたっきり更新しないよーなコードになっておる。

わはは。すまんすまん。UDP から DP に切替えたタイミングでコードをばっさり削った時にいっしょになくなっちゃったんだな。とりあえず適当に追加したものを置いておいた&動かしておいた。

> UDPで試してレスポンスは割ともっちゃりしていたわけだが、クラがジャバだったということもあって一概にネット遅延のせいとは言えん感じがした。

いやぁネット遅延も大きいよ。何しろ我が家は無線 LAN 環境だからして。ルータは遅い Linux box だし。 試しに DP Reflector を動かしてるサーバから 外部 DNS サーバに query かけてみると、大体 50〜80ms くらいはかかる。条件の悪いクライアントとの通信だときっともっと遅いだろうね。
Digitune (Mon, 12 Jul 2004 09:35:00)
> C++だとかなりヤバーな非同期コードも Java だとそうでもないのか。

GC を導入することでどれほどプログラミングモデルが単純になるか、の良い例ともいえるな。だから昨今のプログラミング言語は軒並 GC を持っている。GC による負荷もずいぶん低減されてきたからね。

あと、同期プリミティブとしてインスタンス自体を使える、という Java の設計も物事を単純化するのに良いように働いている。ここでいちいち Mutex 作って…とかやってたらめんどくさくてたまらん。
Digitune (Mon, 12 Jul 2004 09:39:23)
> ブロードキャストすれば。

LIST を使えば、かな。まぁいかようにでもやり方はあろうよ。
Digitune (Mon, 12 Jul 2004 12:32:57)
一例をば。

前提:各クライアントは、ENTRY 後必ず HELLO メッセージとして自分の名前 (と知っていれば部屋の名前) を含むパケットをブロードキャストする。HELLO を受け取った他のクライアントは、自分が部屋名を知らない、かつ HELLO に部屋名が含まれていればそれを採用し、HELLO への返答 (名前は適当に付けるように) として自分の名前 (知っていれば部屋の名前) を含むパケットを HELLO したクライアントにユニキャストする。

部屋の名前付けシーケンス:
1. ENTRY
2. HELLO をブロードキャスト
3. しばし待つ (数秒程度)。返答で部屋名が得られれば終了。
4. ENTRY で割り振られたクライアント ID が 0 だったら 6. (名前づけフェーズ) へ
5. ディスコネクトして 1. からやり直し。
6. ユーザから部屋の名前を入力してもらう。
7. その名前を含む HELLO を再度ブロードキャスト

てな感じ。0 番クライアントがたまたま通信不良を起こした場合に上記シーケンスが完了するまで最長30秒以上かかることもあるが、まぁレアケースだ。

あと、能動的にディスコネクトする手段がないのは不便なのでこれは後で追加しておこう。
かぴのすけ (Mon, 12 Jul 2004 21:47:59)
> 逆に言えばそれだけプログラマの負担が減っている

> GC を導入することでどれほどプログラミングモデルが単純になるか

なぜ多重レスするか。ゲェムキゥブいーよね。Java はなんかキモい。もっちゃり王。
クルーソー化ツール。

> ActiveDesktop とか

あれは盲腸じゃなくて垢とかなんだよ。ほにうるいの成長には必要なことだ。

> 昨今の「日刊 Windows 不具合通信」のような状況を見ても

まーいーじゃん。不具合がまったくなくなったらさみしくなるだろ。
あんま騒がれないだけで他の環境もバリバリ不具合出てるし。

あっち直したらこっちに不具合出る、なんてーのはそんじょそこらのプロ(という肩書き)のコーダーさんでも年中やらかしてるこった。こいつらのダメ仕事は別に騒がれないっつーだけで。
例えば最近だと、サーバの安定性を上げるために仕様を変更したら、勝手にエントリ切られるバグを混入させてしまったとかなんとかいう話があったYO!。

> ネット遅延も大きいよ

ping は 30ms で来るんだがな。

> 一例をば

要するにチャネルの最初のクラにID=0が与えられるという裏仕様なのか。
最初であるという情報さえ分かればフローなど自明よの。

で、グループ名リスト、空きチャネルあるいはグループ名に対応するチャネルを得ようとか思ったらチャネル番号を頭からなめていけと。まあリスト取ってもコロコロ変わっちまうわけだが。
Digitune (Mon, 12 Jul 2004 22:09:03)
> 例えば最近だと、サーバの安定性を上げるために仕様を変更したら、勝手にエントリ切られるバグを混入させてしまったとかなんとかいう話があったYO!。

わはは。まったくまったく。こういうケアレスミスを減らすにはやっぱり UnitTest が有効だよなー。小さい単位で固く作って、結合ポイント毎のテストもしっかりやる。組み合わせ爆発しそうな箇所は極力単純化。

> 要するにチャネルの最初のクラにID=0が与えられるという裏仕様なのか。
> 最初であるという情報さえ分かればフローなど自明よの。

裏仕様もなにも、ソースが開示されてるんだから全て自明な仕様だろー。ちなみにチャネルの最初のクライアントに ID=0 が与えられることは間違いないが、ID=0 が来たからといって最初のクライアントだとは限らない。まぁ理解しているとは思うが。

> で、グループ名リスト、空きチャネルあるいはグループ名に対応するチャネルを得ようとか思ったらチャネル番号を頭からなめていけと。まあリスト取ってもコロコロ変わっちまうわけだが。

そういうことだ。チャネルは 256 本あるが別に全部使う必要ないし。コロコロ変わるとはいえ一覧表示に使うだけならそれほど厳密でなくても構わんだろう (極力タイムアウトが起きないようなシーケンスでざっくりルーム名を得るロジックを作る)。

ルーム、という概念をもっと明確化したい (入室前にメンバーが知りたいとか、人数制限をかけたいとか) となると、また別のサーバとして特殊化していくことになると思うが、まぁ今回のものはあくまでも Reflector なんで。UDP Hole Punching 対応の機能は入れるかもしれんが、アプリケーション寄りの機能はあんまり入れる気はないです。
Digitune (Mon, 12 Jul 2004 22:11:31)
> なぜ多重レスするか。ゲェムキゥブいーよね。Java はなんかキモい。もっちゃり王。
> クルーソー化ツール。

それは投稿してからもっと書きたいことが出てくるから。「クルーソー化ツール」なんて最高じゃないか。そういやクライアントをわざわざ Java で書く必要はないだろう。これまでの C のクライアントを適当に改造すればいいじゃん。
Digitune (Mon, 12 Jul 2004 23:06:18)
さっきサーバリスタートしたぞー。
Digitune (Mon, 12 Jul 2004 23:12:08)
というわけで、UDP hole punching 対応と EXIT 要求に対応したバージョンを置いておきました&動かしておきました。例のよって例のごとくまったくテストしていないので、こないだのようなあからさまなバグがあるかもしれませんがご勘弁あれ。報告いただければ直します。

  1. 言ってみれば TCP を作る時に先人がさんざん考えたことなわけで。 ↩︎