2016-05-20 3 views
0

Я подключаюсь к TCP-серверу с использованием класса TCPSocket Ruby.Как подождать, пока ответ сокета TCP не будет готов

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

Когда я использовал socket.readpartial(), я получил ответ двух белых пробелов.

Я временно решил это с помощью sleep(5), но мне это совсем не нравится, потому что оно хакерское и неуклюжие, и я рискую, что даже через 5 секунд ответ не готов, и я все равно получаю пустой ответ.

Я знаю, что ответы будут всегда содержать 285 символов.

Есть ли более правильный и элегантный способ подключения к TCP-порту полного ответа?

Вот мой код:

def matchgeocode(rua, nro, cidade, uf) 
    count = 0 

    begin 
     socket = TCPSocket.new(GEOCODER_URL, GEOCODER_PORT) 

     # Needed for authentication 
     socket.write("TICKET #{GEOCODER_TICKET}") 

     socket.read(2) 

     # Here's the message I send to the server 
     socket.write("MATCHGEOCODE -Rua:\"#{rua}\" -Nro:#{nro} -Cidade:\"#{cidade}\" -Uf:\"#{uf}\"") 

     # My hackish sleep 
     sleep(5) 

     # Reading the fixed size response 
     response = socket.readpartial(285) 

     socket.write('QUIT') 
     socket.close 
    rescue Exception => e 
     count += 1 
     puts e.message 

     if count <= 5 && response.eql?('') 
     retry 
     end 
    end 

    response  
    end 
+1

Это не моя область знаний, но по умолчанию блокировка IO сокета не является? Если вы попытаетесь прочитать и данные еще не прочитаны, не следует блокировать Ruby до тех пор, пока данные не будут доступны? –

+0

AFAIK да, но когда я просто жду, я всегда получаю пустые ответы, я не получаю правильный ответ, пока не добавлю вызов сна. – Pankas

+1

Почему вы используете 'readpartial'? Не читает (285) 'делать то, что вы хотите? – matt

ответ

1

Поскольку вы знаете длину ответа, вы должны использовать read, не readpartial.

readpartial немедленно возвращается, если доступны ЛЮБЫЕ данные, даже одного байта. Вот почему вам нужен вызов sleep, чтобы ответ успел вернуться к вам до того, как readpartial попытается заглянуть, какие данные имеются.

read с другой стороны блокирует полностью до тех пор, пока не будут доступны запрошенные данные. Поскольку вы знаете длину результата, то read - естественное решение здесь.

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