2015-01-04 2 views
0

Я реализовал очень простой вид сервера в Ruby, используя TCPServer. У меня есть Server класс с serve методом:Ruby TCPServer не работает иногда

def serve 
    # Do the actual serving in a child process 
    @pid = fork do 
     # Trap signal sent by #stop or by pressing ^C 
     Signal.trap('INT') { exit } 

     # Create a new server on port 2835 (1 ounce = 28.35 grams) 
     server = TCPServer.new('localhost', 2835) 
     @logger.info 'Listening on http://localhost:2835...' 

     loop do 
     socket = server.accept 
     request_line = socket.gets 

     @logger.info "* #{request_line}" 

     socket.print "message" 

     socket.close 
     end 
    end 
    end 

и stop метод:

def stop 
    @logger.info 'Shutting down' 
    Process.kill('INT', @pid) 
    Process.wait 
    @pid = nil 
end 

Я бегу мой сервер из командной строки, используя:

if __FILE__ == $0 
    server = Server.new 
    server.logger = Logger.new(STDOUT) 
    server.logger.formatter = proc { |severity, datetime, progname, msg| "#{msg}\n" } 
    begin 
    server.serve 
    Process.wait 
    rescue Interrupt 
    server.stop 
    end 
end 

Проблема заключается в том, что , иногда, когда я делаю ruby server.rb с моего терминала, сервер запускается, но когда я пытаюсь сделать запрос на localhost:2835, он терпит неудачу. Только после нескольких запросов он начинает обслуживать некоторые страницы. В других случаях мне нужно снова остановить/запустить сервер, чтобы он правильно обслуживал страницы. Почему это происходит? Я делаю что-то неправильно? Я нахожу это очень странным ...

То же самое относится к моим спецификациям: у меня есть определенные спецификации и некоторые спецификации Capybara. Перед каждым тестом я создаю сервер и запускаю его, и после каждого теста я останавливаю сервер. И проблема сохраняется: тесты иногда проходят, иногда сбой, потому что запрошенная страница не найдена.

Есть ли что-то рыбное с моим fork ing?

бы признателен любой ответ, потому что у меня нет больше места, чтобы посмотреть ...

+0

Ваш код работает надежно, когда я запускаю его. Как вы делаете запросы на свой сервер? Я использую 'nc'. – Adrian

+0

Классический способ: открытие браузера на 'localhost: 2835'. И в тестах, «классический» способ Capybara, с «посещением» localhost: 2833''. – linkyndy

+0

Это твоя проблема. Если вы хотите посетить 'localhost: 2835' в своем браузере, вам нужно реализовать HTTP-сервер. Код, который вы отправили, не является HTTP-сервером. – Adrian

ответ

0

Ваш код не является сервером HTTP. Это TCP-сервер, который отправляет строку «сообщение» через сокет после получения новой строки.

Причина, по которой ваш код не является допустимым HTTP-сервером, заключается в том, что он не соответствует HTTP protocol. Одна из многих требований протокола HTTP в том, что сервер ответит сообщение формы

HTTP/1.1 <code> <reason> 

Где <code> это число и <reason> является читаемым человеком «статус», как «OK» или «Сервер Ошибка "или что-то в этом роде. Строка message явно не соответствует этому требованию.

Вот простое введение в том, как вы можете создать сервер HTTP рубина: https://practicingruby.com/articles/implementing-an-http-file-server

+0

. Теперь я понимаю вашу точку зрения. У меня есть HTTP-сервер, я только что подрезал свой код, чтобы вопрос оставался читаемым. Тем не менее, тот факт, что ** иногда ** мне удается успешно обслуживать страницу, должен привести к тому, что сервер будет реализован правильно. Если бы этого не было, я должен был получить некоторую ошибку ** каждый ** время. После углубления, я заметил, что только Firefox имеет эту проблему; с Chrome (и драйвером Chrome Selenium Chrome в Capybara) я не мог воспроизвести эту проблему, независимо от того, сколько раз я загружал страницу/запускал тесты. Может быть, это должна быть какая-то подсказка? – linkyndy

+0

Ну, я могу без всяких сомнений утверждать, что с кодом в вашем вопросе нет ничего плохого.Если у вас возникли проблемы с вашим фактическим кодом, это означает, что есть проблема в том, что отсутствует в этом коде. – Adrian

+0

Какой браузер вы использовали для тестирования вышеуказанного кода? – linkyndy

Смежные вопросы