EventMachine :: HttpRequest и постоянно действующее соединение

#ruby #eventmachine

#ruby #eventmachine

Вопрос:

Я использую следующий код для запуска пары HTTP-запросов, но второй запрос (req2) всегда возвращает ошибку.

Я упускаю что-то очевидное здесь?

 request_options = {
  :body => " ",
  :keepalive => true,
  :head => {
    'content-type' => 'application/json',
    'accept' => 'application/json',
    'Accept-Encoding' => 'gzip,deflate,sdch'
  }
}

EM.run do
  request_options[:path] = '/default/path'

  conn = EM::HttpRequest.new 'https://www.example.com'

  req1 = conn.post request_options
  req1.errback { p 'Uh, oh'; EM.stop }
  req1.callback do
    doc = JSON.parse req1.response

    # do stuff with doc

    request_options[:body] = 'post-data'
    request_options[:path] = '/new/path'

    req2 = conn.post request_options
    req2.errback { p 'Uh, oh'; EM.stop }
    req2.callback do
       puts req2.response
       EM.stop
    end
  end
end
  

Комментарии:

1. Быстрая вещь, которую вы можете попробовать, это использовать разные копии request_options хэша для двух запросов. Возможно, EM::HttpRequest это неаккуратно и изменяет заданный хэш параметров (а затем вы передаете измененный хэш своему следующему вызову, думая, что это так, как вы его настроили, хотя на самом деле все по-другому).

2. Спасибо за ваш ответ. Я только что попробовал это, но он все равно возвращается к ошибке.

3. Жаль, было бы неплохо, если бы это было так просто (но я подумал, что это неправильный ответ, отсюда и комментарий).

Ответ №1:

Я решил свою проблему, используя EM-Synchrony

 gem install em-synchrony
  

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

 request_options = {
  :body => " ",
  :keepalive => true,
  :head => {
    'content-type' => 'application/json',
    'accept' => 'application/json',
    'Accept-Encoding' => 'gzip,deflate,sdch'
  }
}

EM.synchrony do
  request_options[:path] = '/default/path'

  conn = EM::HttpRequest.new 'https://www.example.com'

  req1 = conn.post request_options
  doc = JSON.parse req1.response

  # do stuff with doc

  request_options[:body] = 'post-data'
  request_options[:path] = '/new/path'

  req2 = conn.post request_options
  puts req2.response

  EM.stop
end
  

Наверное, я просто был сбит с толку тем, как EM.run выполняет асинхронные запросы и di.

Ответ №2:

Вы не можете использовать один и тот же объект подключения внутри обратного вызова ответа.

Убедитесь, что вы создали новое EM::HttpRequest.new 'https://www.example.com' для второго запроса.