1

私は Node.js (より大きなアプリケーションの特定のケース) に小さなスクリプトを持っています。これは特定のサービスに接続し、定期的に単純な JSON コマンドを送信します。リクエストは「同期的に」送信されるため、最後のレスポンスを受信した後に次のリクエストが送信されます。

残念ながら、時々応答を受け取れません (TCP PUSH がサーバーに送信され、スクリプトは ACK を受信しますが、サーバーからの PUSH はありません)。したがって、スクリプトがハングします。サーバーのバグを示唆していますが、同じスクリプトがPythonでも書かれており、完全に機能します-すべてのリクエストが応答を受け取ります(Pythonスクリプトは17時間以上機能していますが、Node.jsのスクリプトはハングします場合によっては 15 分から 2 時間かかることもあります)。

通信は TLS (node では tls モジュール、python では ssl モジュール) を使用して暗号化されます。観察された唯一の違いは、SSL パケットのサイズにあります。Node の req/res ペアの重量は 53/77 バイトですが、Pythonic スクリプトでは 90/85 バイトです。

サーバーはC#で書かれていますが、それ以上の情報もアクセスもありません(秘密鍵にも到達できません-何が送信されるかを確認します)。

Node で応答を待たない状況もテストしました (write() の呼び出しで小さな関数で setInterval を使用しただけです)。2 ~ 3 つの要求が連続して送信され、そのときだけ応答が返されることがあります。ただし、それらの一部は形式が正しくありません (コンテンツの代わりにメッセージセパレーターのみを受信します。これはサーバー側の問題を示唆していますが、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