Tedious: ConnectionError: Connection lost - schreiben Sie ECONNRESET, wenn Sie eine lange Zeichenfolge einfügen

Erstellt am 16. Juli 2019  ·  9Kommentare  ·  Quelle: tediousjs/tedious

Ich habe eine Tabelle in einer Azure SQL-Datenbank.

CREATE TABLE [dbo].[Owner](
    [OwnerId] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY,
    [Name] [varchar](50) NOT NULL,
    [Signature] [varchar](max) NULL
)

Ich habe versucht, eine sehr lange Zeichenfolge in die Signaturspalte einzufügen. Wenn die packetSize nicht auf 16384 oder höher eingestellt ist, bekomme ich die folgende Ausnahme:

ConnectionError: Connection lost - write ECONNRESET
    at ConnectionError (C:\work\GitRepos\tedious-test\node_modules\tedious\lib\errors.js:13:12)
    at Connection.socketError (C:\work\GitRepos\tedious-test\node_modules\tedious\lib\connection.js:1187:26)
    at Socket.<anonymous> (C:\work\GitRepos\tedious-test\node_modules\tedious\lib\connection.js:1032:14)
    at Socket.emit (events.js:205:15)
    at errorOrDestroy (internal/streams/destroy.js:107:12)
    at onwriteError (_stream_writable.js:438:5)
    at onwrite (_stream_writable.js:459:5)
    at internal/streams/destroy.js:49:7
    at Socket._destroy (net.js:593:3)
    at Socket.destroy (internal/streams/destroy.js:37:8)
Emitted 'error' event at:
    at Connection.socketError (C:\work\GitRepos\tedious-test\node_modules\tedious\lib\connection.js:1187:12)
    at Socket.<anonymous> (C:\work\GitRepos\tedious-test\node_modules\tedious\lib\connection.js:1032:14)
    [... lines matching original stack trace ...]
    at Socket.destroy (internal/streams/destroy.js:37:8)
    at WriteWrap.onWriteComplete [as oncomplete] (internal/stream_base_commons.js:84:12) {
  message: 'Connection lost - write ECONNRESET',
  code: 'ESOCKET'
}

Unten ist mein einfaches Testprogramm. Ich benutze die neuesten mühsam. Auch der Lesevorgang scheint für lange Zeichenfolgen unabhängig von der Paketgröße einwandfrei zu funktionieren. Irgendeine Idee, was ich falsch gemacht habe?

var Connection = require('tedious').Connection;

var config = {
  server: "myserver.database.windows.net",
  options: {
    encrypt: true,
    database: "<mydb>",
    packetSize: 4096,
  },
  authentication: {
    type: "default",
    options: {  
      userName: "<myuser>",
      password: "<mypwd>",
    }
  }
};

var connection = new Connection(config);

connection.on('connect', function(err) {
    // executeStatement();
    executeInsert();
  }
);


var Request = require('tedious').Request;

function executeStatement() {
  /* Read a long string, work fine */
  request = new Request("select OwnerId, Signature From dbo.Owner Where OwnerId = 36", function(err, rowCount) {
    if (err) {
      console.log(err);
    } else {
      console.log(rowCount + ' rows');
    }
  });

  request.on('row', function(columns) {
    columns.forEach(function(column) {
      console.log(column.value);
    });
  });

  connection.execSql(request);
}


function executeInsert() {
  /************************************************
   * Insert a long string, not working when
   *     packetSize = 4096
   * If
   *     packetSize = 16384
   * or higher, insertion works fine.
   *****************************************************/
  let s = '0123456789'.repeat(100000);
  request = new Request("Insert into dbo.Owner VALUES ('Rick', '" + s + "')", function(err, rowCount) {
    if (err) {
      console.log(err);
    } else {
      console.log(rowCount + ' rows');
    }
  });

  connection.execSql(request);
}
released

Hilfreichster Kommentar

Bei einer langen Abfrage Connection lost - read ECONNRESET erhalten. Mit encrypt: true und packetSize: 32768 funktioniert alles einwandfrei.

Knotenversion: v12.6.0

Alle 9 Kommentare

Wir stoßen auf ein ähnliches Problem. beim Versuch, eine lange Zeichenfolge einzufügen. Nach einigem Testen stellt sich heraus, dass es bei uns mit der verwendeten nodejs-Version in unserem Fall dockerized zusammenhängt.
node:10-slim -> funktioniert gut
node:12.3.1 -> funktioniert gut
Das Starten von node:12.4 führt entweder zu einem Socket-Hangup- oder Socket-Closed-Fehler.

Hallo @ricklang , ich habe das hier gesucht. Ist "encrypt: true" eine erforderliche Einstellung auf Ihrer Seite? Wenn dies nicht der Fall ist, setzen Sie es auf "false" oder setzen Sie es einfach nicht in der Option, wodurch die Verwendung des Standardwerts -false diese Probleme ebenfalls lösen kann. Ich habe versucht herauszufinden, warum dies geschieht, aber ich habe keine Ursache dafür gefunden. Ich habe die Pakete sowohl auf verschlüsselte als auch auf nicht verschlüsselte Verbindungen überprüft, die Pakete sind genau gleich, aber zum Verschlüsseln eines Pakets wird beim Empfang des letzten Pakets mit EOM der Fehler "Verbindung verloren" empfangen. Ich werde ein bisschen mehr Nachforschungen anstellen, sehen, ob ich etwas ausgraben kann.
Andererseits könnten wir auch @arthurschreiber danach fragen, ob er einen Einblick hat.

Mit

encrypt: false,

Fehlermeldung ist (unabhängig von der Paketgröße):

RequestError: Requests can only be made in the LoggedIn state, not the SentPrelogin state
    at RequestError (C:\work\GitRepos\tedious-test\node_modules\tedious\lib\errors.js:32:12)
    at Connection.makeRequest (C:\work\GitRepos\tedious-test\node_modules\tedious\lib\connection.js:1680:24)
    at Connection.execSql (C:\work\GitRepos\tedious-test\node_modules\tedious\lib\connection.js:1459:10)
    at executeInsert (C:\work\GitRepos\tedious-test\index.js:67:14)
    at Connection.<anonymous> (C:\work\GitRepos\tedious-test\index.js:24:5)
    at Connection.emit (events.js:200:13)
    at Connection.message (C:\work\GitRepos\tedious-test\node_modules\tedious\lib\connection.js:1871:18)
    at Connection.dispatchEvent (C:\work\GitRepos\tedious-test\node_modules\tedious\lib\connection.js:1172:36)
    at MessageIO.<anonymous> (C:\work\GitRepos\tedious-test\node_modules\tedious\lib\connection.js:1045:14)
    at MessageIO.emit (events.js:200:13) {
  message: 'Requests can only be made in the ' +
    'LoggedIn state, not the SentPrelogin ' +
    'state',
  code: 'EINVALIDSTATE'

Wenn Sie die Verschlüsselungseinstellung entfernen, aber die Paketgröße auf 4096 belassen, lautet die Fehlermeldung:

ConnectionError: Connection lost - write ECONNRESET
    at ConnectionError (C:\work\GitRepos\tedious-test\node_modules\tedious\lib\errors.js:13:12)
    at Connection.socketError (C:\work\GitRepos\tedious-test\node_modules\tedious\lib\connection.js:1187:26)
    at Socket.<anonymous> (C:\work\GitRepos\tedious-test\node_modules\tedious\lib\connection.js:1032:14)
    at Socket.emit (events.js:205:15)
    at errorOrDestroy (internal/streams/destroy.js:107:12)
    at onwriteError (_stream_writable.js:438:5)
    at onwrite (_stream_writable.js:459:5)
    at internal/streams/destroy.js:49:7
    at Socket._destroy (net.js:593:3)
    at Socket.destroy (internal/streams/destroy.js:37:8)
Emitted 'error' event at:
    at Connection.socketError (C:\work\GitRepos\tedious-test\node_modules\tedious\lib\connection.js:1187:12)
    at Socket.<anonymous> (C:\work\GitRepos\tedious-test\node_modules\tedious\lib\connection.js:1032:14)
    [... lines matching original stack trace ...]
    at Socket.destroy (internal/streams/destroy.js:37:8)
    at WriteWrap.onWriteComplete [as oncomplete] (internal/stream_base_commons.js:84:12) {
  message: 'Connection lost - write ECONNRESET',
  code: 'ESOCKET'

Aber wenn die Paketgröße ohne Verschlüsselungssatz auf 16384 erhöht wird, funktioniert alles einwandfrei.

Übrigens habe ich auf Knotenversionen getestet: 12.4.0, 12.6.0. Gleiche Ergebnisse.

Bei einer langen Abfrage Connection lost - read ECONNRESET erhalten. Mit encrypt: true und packetSize: 32768 funktioniert alles einwandfrei.

Knotenversion: v12.6.0

@ wy193777 könnten Sie überprüfen, ob alles ohne zusätzliche Optionen funktioniert und die Knotenversion maximal 12.3.1 verwendet?

@susares node v12.3.1 funktioniert ohne die Option packetSize funktioniert bei mir.

Knotenversion: v12.2.0 funktioniert ohne die Option packetSize
Knotenversion: v.12.6.0 erforderte die Verwendung packetSize: 8192 , um den Fehler Connection lost - read ECONNRESET #$ zu vermeiden

Dies scheint auf https://github.com/nodejs/node/pull/27861 zurückzuführen zu sein. Irgendwie beendet SQLServer die Verbindung, wenn große TLS-Segmente geschrieben werden. Ich habe eine Lösung und werde in Kürze eine PR öffnen. 👍

Für diejenigen, die es kaum erwarten können, hier ist der Unterschied, der dies beheben wird:

diff --git a/src/message-io.js b/src/message-io.js
index 90875f8..79f5da8 100644
--- a/src/message-io.js
+++ b/src/message-io.js
@@ -72,6 +72,8 @@ module.exports = class MessageIO extends EventEmitter {
       encrypted: duplexpair.socket2
     };

+    securePair.cleartext.setMaxSendFragment(this.outgoingMessageStream.packetSize);
+
     // If an error happens in the TLS layer, there is nothing we can do about it.
     // Forward the error to the socket so the connection gets properly cleaned up.
     securePair.cleartext.on('error', (err) => {

:tada: Dieses Problem wurde in Version 6.2.1 behoben :tada:

Die Ausgabe ist verfügbar unter:

Ihr Semantic-Release- Bot :package::rocket:

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen