1

我在 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)

该命令略有不同,但已经测试了具有相同确切字符串的版本,结果相同。

4

0 回答 0