У меня есть таблица в базе данных SQL Azure.
CREATE TABLE [dbo].[Owner](
[OwnerId] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY,
[Name] [varchar](50) NOT NULL,
[Signature] [varchar](max) NULL
)
Я попытался вставить очень длинную строку в столбец Подпись. Если для packageSize не установлено значение 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);
}
Мы столкнулись с похожей проблемой. при попытке вставить длинную строку. После небольшого тестирования выясняется, что для нас это связано с используемой версией nodejs в нашем случае dockerized.
узел: 10-тонкий -> отлично работает
узел: 12.3.1 -> отлично работает
начальный узел: 12.4 приводит либо к зависанию сокета, либо к ошибке закрытия сокета.
Привет @ricklang , я искал это. Является ли «шифрование: true» обязательным параметром на вашей стороне? Если это не так, установите для него значение false или просто не устанавливайте его в опции, которая с использованием значения по умолчанию -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 wy193777 , не могли бы вы проверить, все ли работает без дополнительных опций и с максимальной версией узла 12.3.1?
Узел @susares v12.3.1 работает без опции packageSize, которая у меня работает.
версия узла: v12.2.0 работает без параметра packageSize
версия узла: v.12.6.0 требовал, чтобы я использовал packetSize: 8192
, чтобы избежать ошибки Connection lost - read ECONNRESET
Кажется, это связано с https://github.com/nodejs/node/pull/27861. Каким-то образом SQLServer завершит соединение, если будут записаны большие сегменты TLS. У меня есть исправление, и я скоро открою PR. 👍
Для тех, кто не может ждать, вот diff, который это исправит:
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:
Самый полезный комментарий
Получил
Connection lost - read ECONNRESET
при выполнении длинного запроса. Сencrypt: true
иpacketSize: 32768
все работает нормально.версия узла:
v12.6.0