Tedious: خطأ في الاتصال: فُقد الاتصال - اكتب ECONNRESET عند إدخال سلسلة طويلة

تم إنشاؤها على ١٦ يوليو ٢٠١٩  ·  9تعليقات  ·  مصدر: tediousjs/tedious

لدي جدول في قاعدة بيانات Azure SQL.

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

حاولت إدخال سلسلة طويلة جدًا في عمود التوقيع. إذا لم يتم تعيين packetSize على 16384 أو أعلى ، فقد حصلت على الاستثناء التالي:

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'
}

يوجد أدناه برنامج الاختبار البسيط الخاص بي. أنا استخدم أحدث مملة. يبدو أيضًا أن عملية القراءة تعمل بشكل جيد مع سلسلة طويلة بغض النظر عن حجم الحزمة. أي فكرة عما فعلته خطأ؟

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

التعليق الأكثر فائدة

حصلت على Connection lost - read ECONNRESET عند إجراء استعلام طويل. مع encrypt: true و packetSize: 32768 ، كل شيء يعمل بشكل جيد.

إصدار العقدة: v12.6.0

ال 9 كومينتر

نواجه مشكلة مماثلة. عند محاولة إدخال سلسلة طويلة. بعد قليل من الاختبار ، اتضح أنه بالنسبة لنا مرتبط بإصدار nodejs المستخدم في حالتنا.
العقدة: 10-Slim -> تعمل بشكل جيد
العقدة: 12.3.1 -> تعمل بشكل جيد
عقدة البداية: ينتج عن 12.4 خطأ إغلاق مأخذ التوصيل أو إغلاق مأخذ التوصيل.

مرحبًا ricklang ، كنت أبحث في هذا الأمر. هل "التشفير: صحيح" إعداد مطلوب من جانبك؟ إذا لم يكن الأمر كذلك ، فاضبطه على خطأ أو فقط لا تقم بتعيينه في الخيار الذي يمكن أن يؤدي استخدام القيمة الافتراضية - False أيضًا إلى حل هذه المشكلات. كنت أحاول معرفة سبب حدوث ذلك ، لكنني لم أجد سببًا جذريًا لذلك. لقد تحققت من الحزم لكل من الاتصال المشفر وغير المشفر ، والحزم هي نفسها تمامًا ، ولكن لتشفير واحدة ، عند استلام آخر حزمة مع EOM ، يتم تلقي خطأ فقد الاتصال. سأجري المزيد من التحقيق ، لنرى ما إذا كان بإمكاني التنقيب عن أي شيء.
من ناحية أخرى ، يمكننا أيضًا سؤال arthurschreiber عن هذا الأمر ، ومعرفة ما إذا كان لديه أي فكرة.

مع

encrypt: false,

رسالة الخطأ هي (بغض النظر عن حجم الحزمة):

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'

في حالة إزالة إعداد التشفير ، مع ترك حجم الحزمة عند 4096 ، فإن رسالة الخطأ هي:

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'

ولكن إذا زاد حجم الحزمة إلى 16384 بدون مجموعة تشفير ، فإن كل شيء يعمل بشكل جيد.

بالمناسبة ، اختبرت إصدارات العقدة: 12.4.0 ، 12.6.0. نفس النتائج.

حصلت على Connection lost - read ECONNRESET عند إجراء استعلام طويل. مع encrypt: true و packetSize: 32768 ، كل شيء يعمل بشكل جيد.

إصدار العقدة: v12.6.0

@ wy193777 هل يمكنك التحقق مما إذا كان كل شيء يعمل بدون خيارات إضافية واستخدام إصدار العقدة بحد أقصى 12.3.1؟

susares العقدة v12.3.1 تعمل بدون خيار packetSize يعمل بالنسبة لي.

إصدار العقدة: v12.2.0 يعمل بدون خيار packetSize
إصدار العقدة: v.12.6.0 يتطلب مني استخدام packetSize: 8192 لتجنب الخطأ Connection lost - read ECONNRESET

يبدو أن هذا يرجع إلى https://github.com/nodejs/node/pull/27861. بطريقة ما ، سينهي SQLServer الاتصال إذا تمت كتابة مقاطع TLS كبيرة. لدي إصلاح وسأفتح العلاقات العامة قريبًا. 👍

بالنسبة لأولئك الذين لا يستطيعون الانتظار ، إليك الفرق الذي سيصلح هذا:

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: تم حل هذه المشكلة في الإصدار 6.2.1: tada:

الإصدار متاح في:

روبوت التحرير الدلالي الخاص بك: Package :: Rocket:

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات

القضايا ذات الصلة

spacem picture spacem  ·  4تعليقات

arthurschreiber picture arthurschreiber  ·  8تعليقات

SaloniSonpal picture SaloniSonpal  ·  5تعليقات

tvrprasad picture tvrprasad  ·  6تعليقات

diginfo picture diginfo  ·  6تعليقات