Ruby TCP "бот" с помощью EventMachine - реализация диспетчера команд - PullRequest
1 голос
/ 29 сентября 2011

Я создал базовый TCP-клиент, используя EventMachine.Код:

# run.rb
EventMachine::run do
  EventMachine::connect $config_host, $config_port, Bot
end

# bot.rb
module Bot
  def post_init
    # log us in and do any other spinup.
    sleep(1)
    send_data $config_login + "\n"
    EventMachine.add_periodic_timer($config_keepalive_duration) { send_data $config_keepalive_str + "\n" }
    @valid_command =  /^<#{$config_passphrase}:([^>:]+):(#\d+)>(.*)$/
  end

  def receive_data(data)
    if(ma = @valid_command.match(data))
      command, user, args = ma[1,3]
      args.strip!
      command.downcase!
      p "Received: #{command}, #{user}, #{args}"
      # and.. here we handle the command.
    end
  end
end

Все это работает довольно хорошо.Основная идея заключается в том, что он должен подключиться, прослушать специально отформатированные команды и выполнить команду;при выполнении команды может быть любое количество «действий», которые приводят к различным данным, отправляемым клиентом.

Но для моего следующего трюка мне нужно добавить возможность фактически обрабатывать команды, которыеBot получает.

Я хотел бы сделать это, используя динамическую библиотеку слушателей событий или что-то подобное;у меня есть произвольное количество плагинов, которые могут зарегистрироваться, чтобы прослушать определенную команду и получить обратный вызов от bot.rb.(В конце концов, я бы тоже хотел иметь возможность перезагрузить эти плагины без перезагрузки бота.)

Я посмотрел на гем ruby_events и думаю, что это имеет смысл, но у менянебольшая проблема в выяснении лучшего способа создания вещей.Мои вопросы включают в себя ...

  1. Я немного озадачен, куда присоединить ruby_events слушателей - он просто расширяет Object, поэтому он не дает понять, как его реализовать.
  2. Bot - это модуль, поэтому я не могу просто позвонить Bot.send_data из одного из плагинов для отправки данных - как я могу взаимодействовать с подключением EM из одного из плагинов?

Я полностью открыт для любых архитектурных изменений или предложений других драгоценных камней, которые также облегчают то, что я пытаюсь сделать.

1 Ответ

2 голосов
/ 29 сентября 2011

Я не уверен, что именно вы пытаетесь сделать, но один из распространенных способов сделать это в EM - определить обработчики команд как обратные вызовы.Таким образом, командную логику можно вытолкнуть из самого модуля Bot, который просто обрабатывает базовый обмен данными между сокетами и анализ команд.Подумайте о том, как веб-сервер отправляет приложение - веб-сервер не выполняет работу, он просто отправляет.

Например, что-то вроде этого

EM::run do 

  bot = EM::connect $config_host, $config_port, Bot

  bot.on_command_1 do |user, *args|
     # handle command_1 in a block
  end

  # or if you want to modularize it, something like this
  # where Command2Handler = lambda {|user, *args| #... }
  bot.on_command_2(&Command2Handler)

end

Итак, вам просто нужнореализовать #on_command_1, #on_command_2 и т. д. в вашем боте, что является просто вопросом хранения проков для экземпляров vars;затем вызывая их, как только вы проанализируете переданные команды из вашего receive_data.

Хороший, очень читаемый пример этого в работе: TwitterStream .

...