Eu tenho uma tabela em um banco de dados SQL do Azure.
CREATE TABLE [dbo].[Owner](
[OwnerId] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY,
[Name] [varchar](50) NOT NULL,
[Signature] [varchar](max) NULL
)
Tentei inserir uma string muito longa na coluna Signature. Se o packetSize não estiver definido como 16384 ou superior, recebi a seguinte exceção:
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'
}
Abaixo está o meu programa de teste simples. Eu uso o mais recente tedioso. Além disso, a operação de leitura parece funcionar bem para strings longas, independentemente do tamanho do pacote. Alguma ideia do que fiz de errado?
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);
}
Nós nos deparamos com um problema semelhante. ao tentar inserir uma string longa. Após um pouco de teste, verifica-se que para nós está relacionado à versão nodejs usada em nosso caso dockerized.
node:10-slim -> funciona bem
node:12.3.1 -> funciona bem
o nó inicial: 12.4 resulta em um erro de desligamento de soquete ou de fechamento de soquete.
Oi @ricklang , eu estava procurando por isso. "encrypt: true" é uma configuração necessária do seu lado? Se não for, defina-o como false ou apenas não o defina na opção que, usando o valor padrão -false, também pode resolver esses problemas. Eu estava tentando descobrir por que isso está acontecendo, mas não encontrei uma causa raiz para isso. Verifiquei os pacotes para conexão criptografada e não criptografada, os pacotes são exatamente os mesmos, mas para criptografar um, quando o último pacote com EOM é recebido, o erro de perda de conexão é recebido. Vou dar um pouco mais de investigação, ver se consigo desenterrar alguma coisa.
Por outro lado, também poderíamos perguntar ao @arthurschreiber sobre isso, ver se ele tem alguma dica.
Com
encrypt: false,
A mensagem de erro é (não importa o tamanho do pacote):
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'
Se remover a configuração de criptografia, mas deixar o tamanho do pacote em 4096, a mensagem de erro será:
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'
Mas se aumentar o tamanho do pacote para 16384 sem nenhum conjunto de criptografia, tudo funcionará bem.
A propósito, testei as versões do nó: 12.4.0, 12.6.0. Mesmos resultados.
Obteve Connection lost - read ECONNRESET
ao executar uma consulta longa. Com encrypt: true
e packetSize: 32768
, tudo funciona bem.
versão do nó: v12.6.0
@ wy193777 você poderia verificar se tudo funciona sem opções adicionais e usando a versão do nó no máximo 12.3.1?
@susares node v12.3.1 funciona sem a opção packetSize funciona para mim.
versão do nó: v12.2.0 funciona sem a opção packetSize
versão do nó: v.12.6.0 exigiu que eu usasse packetSize: 8192
para evitar o erro Connection lost - read ECONNRESET
Isso parece ser devido a https://github.com/nodejs/node/pull/27861. De alguma forma, o SQLServer encerrará a conexão se grandes segmentos TLS forem gravados. Eu tenho uma correção e vou abrir um PR em breve. 👍
Para aqueles que não podem esperar, aqui está o diff que corrigirá isso:
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: Este problema foi resolvido na versão 6.2.1 :tada:
O lançamento está disponível em:
Seu bot de lançamento semântico :package::rocket:
Comentários muito úteis
Obteve
Connection lost - read ECONNRESET
ao executar uma consulta longa. Comencrypt: true
epacketSize: 32768
, tudo funciona bem.versão do nó:
v12.6.0