【发布时间】:2016-08-24 09:15:11
【问题描述】:
我从最近的一个 ruby 项目中获得了以下(简化的)代码,用于可读和可写的流:
class StreamReader
require 'socket'
require 'openssl'
OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
def initialize
tcp_client = TCPSocket.new ENV['URL'], ENV['PORT']
context = OpenSSL::SSL::SSLContext.new
context.ssl_version = :TLSv1_2
context.verify_mode = OpenSSL::SSL::VERIFY_PEER
cert_store = OpenSSL::X509::Store.new
cert_store.set_default_paths
context.cert_store = cert_store
@stream_client = OpenSSL::SSL::SSLSocket.new tcp_client, context
@stream_client.connect
@requester = StreamRequester.new
end
def open_stream
login = @requester.create_login_request
@stream_client.puts login
loop do
line = @live_client.gets
puts line.strip if !line.strip.empty?
end
end
end
这样我就可以跑了:
stream = StreamReader.new
stream.open_stream
它会打印出数据。
现在我正在尝试使用 nodejs 6.4.0 打开提要,但我无法理解它。
我认为我需要一个net.Socket,然后将它传递给一个tls.TLSSocket,它将返回一个双工流。但我不知道如何设置它。 TLS 建立在 OpenSSL 之上,因此它应该能够做同样的事情。
这是我目前的设置:
var net = require('net');
var tls = require('tls');
var HOST = 'some.url.com';
var PORT = 1234;
var loginRequest = "<Request type='login' user='user' password='pass'></Request>"
//create net.Socket
var socket = new net.Socket();
socket.connect({port: PORT, host: HOST})
var tlsSocket = new tls.TLSSocket(socket,{requestCert:false})
tlsSocket.setEncoding("UTF-8")
//Listen for connect
socket.on("connect",function(){
console.log("connected to",HOST)
tlsSocket.write(loginRequest,function (){
console.log("request sent")
})
})
tlsSocket.on("error",function(err){
console.log("ERROR:",err)
})
tlsSocket.on("close",function(){
console.log("CLOSING")
})
tlsSocket.on("end",function(){
console.log("END")
})
tlsSocket.on("data",function(data){
console.log("DATA:",data)
})
tlsSocket.on("readable",function(){
console.log("SOMETHING TO READ")
console.log(tlsSocket.read())
})
打印出来
connected to some.url.com
request sent
SOMETHING TO READ
null
END
CLOSING
正如https://nodejs.org/dist/latest-v6.x/docs/api/stream.html#stream_event_readable 中所说,readable 在end 之前发出,在这种情况下数据是null。提供公司无法就该主题提供帮助,只有他们知道原因。我需要帮助才能使它像在 ruby sn-p 中一样工作。
任何帮助表示赞赏。
【问题讨论】:
-
您确定您发送的请求有效吗?您不需要某种“请求结束”标记(例如 CR 和/或 LF)吗?您是立即收到“可读”事件,还是延迟后收到?例如,您是否尝试过使用
openssl s_client“手动”发送相同的请求? -
@jcaron 这与 ruby sn-p 中的请求完全相同。我在 ruby sn-p 中使用了 xmlbuilder,但 xmlstring 也可以。刚刚检查过了。可读事件在短暂延迟(1-2 秒)后出现。手动发送有效。
-
echo -e "<Request type='login' user='user' password='pass'></Request>" | openssl s_client -connect some.url.com:1234 -ign_eof马上开始。 -
echo添加一个 LF(除非您使用-n)。你可能需要在你的 JS 代码中做同样的事情。 -
@jcaron 非常感谢!将
\n添加到loginRequest工作!