我正在尝试编写一个Ruby websocket客户端。我可以通过包装在SSLSocket中的TCPSocket进行连接,发送初始握手并接收预期的响应(HTTP / 1.1 101交换协议,以及正确的Sec-Websocket-Accept密钥等)。但是,在websocket框架中发送第一条消息后,我无法读取响应。使用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调试器中,发送消息后,我可以使用read_non_block()从SSL-TCP套接字读取4个字节: “ \ x88 \ x02 \ x03 \ xE8” 要么
下面是我的代码的摘录。
@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
执行卡在最后一行。
如何正确读取连接到websocket服务器的SSL-TCP套接字?
(我正在运行Ubuntu 18.04和Ruby-2.6.0)