IRC Lite演習の実装

チャットサーバとクライアントのテスト

チャットサーバとクライアントのテスト


『プログラミングErlang』11.7に載っている演習の実演。サーバをVMware上のUbuntuで動かし、ホスト側のMac OS Xと合わせて計6つのクライアント・ウィンドウを開いている。グループは2つあり、「Miki」というユーザは両方のグループに(それぞれ別のクライアントとして)ログインしている。

グループの全員の名前を表示するコードを追加してみよう
→ gsのlistboxオブジェクトを使用して実装した
すべてのグループの一覧を表示するコードを追加してみよう
→ 同じくgsのlistboxを使用して実装した
1対1の会話を追加してみよう
→ メンバー一覧の中からユーザ名を選んでメッセージ送信を行うと、そのユーザに対してのみメッセージが届くようにした(スクリーンショット中「765pro」グループの「Haruka」と「Miki」のやり取り)。また自分を選ぶと自分にだけ表示されるようにした(「Yukiho」のメッセージ)
グループコントローラをサーバマシンで動かさずに、グループに最初に入ったユーザのところで動かすためのコードを追加してみよう
→ どうしても理解できなかったので実装しなかった

以下雑感。

chat_serverとchat_groupはPidを管理するために微妙に異なるデータ構造を使っている。これが非常にイケてない。DRY原則に従って、lib_pid_assocというモジュールを作って統合した。例えば要素を取り除くremove関数は以下の通り。

remove(Pid, Assoc) ->
    remove(Pid, Assoc, []).
 
remove(_,   [], L)             -> {"????", L};
remove(Pid, [{Key, Pid}|T], L) -> {Key, reverse(L, T)};
remove(Pid, [H|T], L)          -> remove(Pid, T, [H|L]).

gsのlistboxオブジェクトは、一度何かのアイテムを選択してしまうと、マウス操作では非選択状態に戻せなくなるらしい(少なくとも私はその方法を発見できなかった)。さすがに不便なので、Membersラベルをクリックしたら選択を解除するコードを追加しておいた。

loop(W) ->
  receive
  %...
        {gs, label_m, buttonpress, _, _} ->
            gs:config(listbox_m, {selection, clear}),
            loop(W);
  %...
  end.

Leave a Reply