読者です 読者をやめる 読者になる 読者になる

とりあえずマルチなechoサーバを試みたら玉砕

ocaml

Eventモジュールの練習として並列的なアプリを作ってみようと思ったのだけど、ネタが出てこなかったので、複数のコネクションを受け付けておいて、一つのコネクションから受信したやつを全てのコネクションに送信するチャットっぽいechoサーバを書いてみようと思った。

いまだに、Eventについてよくわからないものの、とりあえず何も考えず無心で書いてみる…

open Unix
open Event

let rec loop f = f (); loop f
let gone f = ignore (Thread.create loop f)

let world_ch = new_channel ()

let process ich och =
    (* world_ch -> connection *)
    gone (  
        fun () -> 
            output_string och (sync (receive world_ch)); 
            flush och
    );
    (* connection -> world_ch *)
    loop (  
        fun () -> 
            sync (send world_ch (input_line ich))
    )

let _ =
    let sa = ADDR_INET (inet_addr_any, 54321) in
    ignore (establish_server process sa)

world_chがなんか全てうまくやってくれると良いなぁ、という希望を込めてます。

で、いざ起動してみると、各コネクションごとの普通のechoになっちゃう(下記は同時に実施)。

  • client a:
komamitsu@potato:~/lab/ocaml/echovent$ telnet localhost 54321
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
hoge
hoge
  • client b:
komamitsu@potato:~/lab/ocaml/echovent$ telnet localhost 54321
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
lslsls
lslsls

あ〜〜〜receiveされるとchannelから無くなっちゃうから、結局一つのコネクションにしか出力され無いのか…

なるほど、これが「一対多ができない」という意味か。