Невозможно прочитать из TCPSocket после первоначального рукопожатия - PullRequest
0 голосов
/ 21 апреля 2019

Я пытаюсь написать клиент Ruby для веб-сокетов. Я могу подключиться через TCPSocket, завернутый в SSLSocket, отправить первоначальное рукопожатие и получить ожидаемый ответ (HTTP / 1.1 101 протокол переключения, с правильным ключом Sec-Websocket-Accept и т. Д.). Однако после отправки моего первого сообщения в рамке веб-сокета я не могу прочитать ответ. Обнаружение порта с помощью tcpdump означает, что сервер отправляет обратно хотя бы одно сообщение ненулевой длины:

after successful handshake, sending request here:
13:31:00.656516 IP nifty.54930 > streamer-ws-tx.tdameritrade.com.https: Flags [P.], seq 697:1259, ack 3256, win 316, length 562
...
13:31:00.679138 IP streamer-ws-tx.tdameritrade.com.https > nifty.54930: Flags [.], ack 1259, win 2483, length 0

...and getting back 33 bytes of response
13:31:00.679777 IP streamer-ws-tx.tdameritrade.com.https > nifty.54930: Flags [P.], seq 3256:3289, ack 1259, win 2483, length 33
13:31:00.720433 IP nifty.54930 > streamer-ws-tx.tdameritrade.com.https: Flags [.], ack 3289, win 316, length 0
13:31:18.504672 IP nifty.54930 > streamer-ws-tx.tdameritrade.com.https: Flags [F.], seq 1259, ack 3289, win 316, length 0

Я считаю, что сообщение, которое я отправляю после рукопожатия, хорошо отформатировано, потому что я тестировал отправку того же сообщения в консоли Chrome, и там я вижу ожидаемый ответ. В отладчике ruby ​​после отправки сообщения я могу прочитать 4 байта из сокета SSL-TCP с помощью read_non_block (): "\ X88 \ x02 \ x03 \ X Е8" или же

Ниже приведена выдержка из моего кода.

@handshake = WebSocket::Handshake::Client.new(
    url: websocket_url,
    port: 443,
)

server = TCPSocket.new(@handshake.host, @handshake.port)

ctx = OpenSSL::SSL::SSLContext.new
ctx.set_params(verify_mode: OpenSSL::SSL::VERIFY_PEER)
@socket = OpenSSL::SSL::SSLSocket.new(server, ctx).tap do |socket|
  socket.sync_close = true
  socket.connect
end


# send handshake
@socket.puts @handshake.to_s


while ! @handshake.finished?
  s = @socket.gets
  next unless s
  puts s
  @handshake << s
end


if !@handshake.valid?
  print "Fail. Handshake invalid.\n"
  exit(1)
end


frame = WebSocket::Frame::Outgoing::Client.new(
          version: @handshake.version,
          data: JSON.generate(request),
          type: :text)


@socket.puts frame.to_s


frm_in = WebSocket::Frame::Incoming::Client.new(version: @handshake.version)


result = @socket.gets

Выполнение застревает в последней строке.

Как правильно читать из сокета SSL-TCP, подключенного к серверу веб-сокетов?

(у меня Ubuntu 18.04 и Ruby-2.6.0)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...