我在 Node.js 中有一个小脚本(这是一个更大的应用程序的特定案例),它连接到某个服务,然后定期发送简单的 JSON 命令。请求是“同步”发送的,因此在收到最后一个响应后发送下一个请求。
不幸的是,有时我没有收到答案(TCP PUSH 被发送到服务器并且我的脚本收到 ACK,但没有来自服务器的 PUSH)。因此,脚本挂起。这表明服务器中存在错误,但是,相同的脚本也是用 Python 编写的,并且运行良好 - 所有请求都会收到响应(并且 Pythonic 脚本已经工作了 17 多个小时,而来自 Node.js 的脚本则挂起不同,有时在 15 分钟到 2 小时之间)。
通信使用 TLS 加密(节点中的 tls 模块和 python 中的 ssl)。唯一观察到的区别在于 SSL 数据包的大小 - Node 中的请求/响应对重 53/77 字节,而在 Pythonic 脚本中它有 90/85 字节。
服务器是用 C# 编写的,但是,我没有更多信息,也无法访问它(私钥也无法访问 - 我会检查传输的内容)。
我还测试了这种情况,我不等待 Node 中的响应(我只是在小函数上使用 setInterval 并调用 write())。有时连续发送两三个请求,然后我才得到响应。但是,其中一些格式不正确(而不是我只收到消息分隔符的内容 - 这表明服务器端存在问题,但是,这不会出现在 Pythonic 版本中)。
你有什么建议?这个问题可能与 SSL/TLS 有关吗?.NET 的东西?或者也许是节点?在此先感谢您的任何建议。
Node.js 中的代码:
const tls = require('tls');
var carrier = require('carrier');
var client = tls.connect(1111, 'host', {rejectUnauthorized: false}, function() {
var reqNum = 0;
var resCarrierNum = -1; // because there is additional login message
var resClientNum = -1;
client.on('data', function(data) {
resClientNum++;
setTimeout(function() {
client.write('{"command":"getVersion"}');
reqNum++;
}, 400);
});
carrier.carry(client, function(data) {
console.log(data);
var response = JSON.parse(data);
if(!response.status) {
console.log('ERROR' + response.errorCode + ': ' + (response.errorDescr));
}
resCarrierNum++;
}, "utf8", /\n\n/);
client.write(JSON.stringify({
"command" : "login",
"arguments" : {
"userId" : 1,
"password" : ''
}
}));
});
Python中的代码:
import socket
import ssl
import sys
import time
addr = sys.argv[1]
port = int(sys.argv[2])
delay = int(sys.argv[3])
def getDateOfBuild(sslS, counter):
print 'Try', counter, time.asctime()
sslS.send('{"command":"getVersion"}')
sf = sslS.makefile()
while True:
line = sf.readline()
if line == '\n':
break;
if line == '':
print "ERROR: connection closed,", time.asctime()
sys.exit()
print line
s = socket.socket()
sslS = ssl.wrap_socket(s)
sslS.connect((addr, port))
print 'Connected from', sslS.getsockname()
print repr(sslS.getpeername())
counter = 0
sslS.write('{\"command\":\"login\",\"arguments\":{\"userId\":\"\",\"password\":\"\"}}\n')
while True:
getDateOfBuild(sslS, counter)
counter += 1
time.sleep(0.4)
该命令略有不同,但已经测试了具有相同确切字符串的版本,结果相同。