EventMachineで複数のサーバーへパケットを投げつつ片方のサーバーのパケットを捨てるproxyとか

ちょいとヤボ用があって、クライアントからのリクエストを複数のサーバーへ投げて、片方のレスポンスを捨てるスクリプト書いた。

require 'rubygems'
require 'eventmachine'
require 'logger'

$logger = Logger.new(STDOUT)

$config = {:master=>{:host=>'localhost',:port=>15000},
           :dummy=>{:host=>'localhost',:port=>15001},
          }


class TcpDuplicator < EventMachine::Connection
  class ServerConnection < EventMachine::Connection
    attr_accessor :client

    def post_init
      $logger.info {"ServerConnection::post_init"}
    end

    def receive_data data
      $logger.info {"ServerConnection::receive_data #{data}"}
      client.send_data data
    end

    def unbind
      $logger.info { "ServerConnection::unbind" }
      client.close_connection true
    end
  end

  class DummyServerConnection < EventMachine::Connection
    def post_init
      $logger.info{ "DummyServerConnection::post_init"}
    end

    def receive_data data
      $logger.info{"DummyServerConnection::receive_data #{data}"}
    end

    def unbind
      $logger.info {"DummyServerConnection::unbind"}
    end
  end

  def post_init
    $logger.info {"TcpDuplicator::post_init"}
    @master_connection = EventMachine::connect($config[:master][:host],$config[:master][:port], ServerConnection) do |connection|
      connection.client = self
    end
    @dummy_connection = EventMachine::connect($config[:dummy][:host],$config[:dummy][:port], DummyServerConnection) do |connection|
    end
  end

  def receive_data data
    $logger.info {"TcpDuplicator::receive_data #{data}"}
    @master_connection.send_data data
    @dummy_connection.send_data data unless @dummy_connection.nil?
  end

  def unbind
    $logger.info {"TcpDuplicator::unbind"}
    @master_connection.close_connection unless @master_connection.nil?
    @dummy_connection.close_connection unless @dummy_connection.nil?
  end

end

port = ARGV[1].to_i
port = 20002 if port == 0
addr = "0.0.0.0"

EventMachine::run do
  puts "start tcp_duplicator #{addr}:#{port}"
  Signal.trap("INT") { EventMachine.stop }
  Signal.trap("TERM") { EventMachine.stop }
  EventMachine.start_server addr, port, TcpDuplicator
end

puts "shutdown server"