Server::Starter の SYNOPSIS には、自分で Server::Starter 配下で実行するサーバを作る場合の例があります。
# in my_httpd use Server::Starter qw(server_ports); my $listen_sock = IO::Socket::INET->new( Proto => 'tcp', ); $listen_sock->fdopen((values %{server_ports()})[0], 'w') or die "failed to bind to listening socket:$!"; while (1) { if (my $conn = $listen_sock->accept) { ... } }
ところでこのサーバは Perl でなければ書けないのか? というと、そんなことはないのですね。
Server::Starter から起動された場合、環境変数 SERVER_STARTER_PORT に、Listen しているポートと、それに対応する fd (ファイルディスクリプタ) の値が入ってます。
$ start_server -p 3333 my_server
たとえばこうして起動した場合、$SERVER_STARTER_PORT="3333=4" などとなっているので、この fd の値(ここでは 4) を accept すれば Server::Starter 配下で動くサーバを書くことができます。
Ruby ならこんな感じ。
require "socket"; ss_port = ENV['SERVER_STARTER_PORT'] #= "3333=4" port, fd = ss_port.split("=") listen_sock = Socket.for_fd(fd.to_i) while true conn, addr = listen_sock.accept # ... end
C だったら conn = accept(fd, ...) ですね。
起動時に複数 port を指定した場合は、(host:port|port)=fd が ; で繋がれた値になります。
$ start_server -p 127.0.0.1:1234 -p 2345 # 127.0.0.1:1234=4;2345=5
以上、昨日の qpstudy01 で Server::Starter に興味を持たれたかたが多かったような(印象だった)ので書いてみました。