我能夠將啓動消息發送到我正在運行的PostgreSQL服務器並從該服務器獲得響應。我得到ParameterStatus消息。問題是我從來沒有得到任何類型的認證信息。我的問題是:爲什麼服務器從不向我發送任何類型的身份驗證消息?如何使用node.js啓動PostgreSQL消息流協議net.Socket
下面我將向您展示我的代碼片斷,以瞭解協議的啓動部分是如何工作的,以及它爲調試輸出的幾行代碼(以便希望您甚至不必閱讀我的代碼),我認爲是來自PostgreSQL文檔的有用信息,用於理解我的問題以及我發現可用於可視化協議的另一個資源。
這是我的代碼:
var net = require('net');
var BlueBird = require('bluebird');
var Buffer = require('buffer').Buffer;
var createStartupMessage = function(user_name, database_name){
var buffer_size = 22 + user_name.length + 1 + database_name.length + 1 + 1;
var StartUpMessage = new Buffer(buffer_size);
var position_in_buffer = 0;
StartUpMessage.writeUInt32BE(buffer_size, 0);
position_in_buffer += 4;
StartUpMessage.writeUInt32BE(196608, position_in_buffer); //version 3.0
position_in_buffer += 4;
position_in_buffer = addMessageSegment(StartUpMessage, "user", position_in_buffer);
position_in_buffer = addMessageSegment(StartUpMessage, user_name, position_in_buffer);
position_in_buffer = addMessageSegment(StartUpMessage, "database", position_in_buffer);
position_in_buffer = addMessageSegment(StartUpMessage, database_name, position_in_buffer);
//Add the last null terminator to the buffer
addNullTerminatorToMessageSegment(StartUpMessage, position_in_buffer);
console.log("The StartUpMessage looks like this in Hexcode: " + StartUpMessage.toString('hex'));
console.log("The length of the StartupMessage in Hexcode is: " + StartUpMessage.toString('hex').length);
return StartUpMessage;
};
var addMessageSegment = function(StartUpMessage, message_segment, position_in_buffer){
var bytes_in_message_segment = Buffer.byteLength(message_segment);
StartUpMessage.write(message_segment, position_in_buffer, StartUpMessage - position_in_buffer, 'utf8');
position_in_buffer = position_in_buffer + bytes_in_message_segment;
position_in_buffer = addNullTerminatorToMessageSegment(StartUpMessage, position_in_buffer);
return position_in_buffer;
};
var addNullTerminatorToMessageSegment = function(StartUpMessage, position_in_buffer){
StartUpMessage.writeUInt8(0, position_in_buffer);
position_in_buffer = position_in_buffer + 1;
return position_in_buffer;
};
//Here is where everything starts. The functions above are called within this BlueBird Promise.
BlueBird.coroutine(function*() {
var host = "127.0.0.1";
var port = "5432";
var idle_timeout = 10000;
var MySocket = new net.Socket();
MySocket.setTimeout(idle_timeout);
var StartUpMessage = createStartupMessage("testusertwo", "testdatabasetwo");
var data = yield new Promise(
function resolver(resolve, reject) {
var number_of_responses = 0;
var number_of_responses_to_wait_for = 2;
MySocket.on('connect', function() {
var message = StartUpMessage.toString("utf8");
var flushed = MySocket.write(message, "utf8");
console.log("Message flushed to kernel: " + flushed);
});
MySocket.on('data', function (data) {
console.log("The response from the server is: " + data.toString('utf8'));
console.log("----This Line Divides the Response Below from the Response Above----");
if(number_of_responses !== number_of_responses_to_wait_for){
number_of_responses += 1;
} else {
resolve(data);
}
});
MySocket.on('error', function (error) {
reject(error);
});
MySocket.connect(port, host);
}
);
return data;
})()
.then(function (data) {
return data;
})
.catch(function (error) {
console.error(error);
});
這些是爲了調試的目的是什麼我的代碼輸出兩行。它顯示了我發送給服務器的初始utf-8編碼消息的十六進制代碼表示(啓動消息格式通過底部的鏈接顯示在幻燈片9中)。然後顯示服務器響應。
在此之後,我的程序掛起等待,我等待看到它發送一個認證類的消息。在啓動消息中,爲了方便起見,我粗體顯示了前兩個32位Big Endian整數和所有空終止符。另外,最後的標記(在?M2 \ ?? ZI中)實際上是來自utf-8的那些鑽石問號,並且這個結尾部分也在每次運行中都改變。我不知道爲什麼。
從我的代碼的一些輸出:
的StartUpMessage看起來像這樣在十六進制編碼:
**0000003300030000**75736572**00**746573747573657274776f**00**6461746162617365**00**74657374646174616261736574776f**0000**
來自服務器的響應是:
Sapplication_nameSclient_encodingUTF8SDateStyleISO,MDYSinteger_datetimesonSntervalStylepostgresSis_superuseroffSserver_encodingUTF8Sserver_version9.5.0S &會話?_authorizationtestusertwoS#standard_conforming_stringsonSTimeZoneUS/EasternK M2 \ ?? ZI
這是什麼,我認爲是從PostgreSQL文檔相關信息:
50.2.Message Flow.1.Start行動:
要開始會話,前端將打開與服務器的連接併發送啓動消息。
認證週期以服務器拒絕連接嘗試(ErrorResponse)或發送AuthenticationOk結束。
本節說一些其他的事情也使得它聽起來像我應該要麼得到上市(如AuthenticationCleartextPassword消息)的衆多身份驗證信息或AuthenticationOk之一,如果不需要密碼,一切都發生無錯誤。如果有錯誤,那麼我應該得到一個ErrorResponse消息。
50.5.Message格式:
在本節中是表示,如果在服務器響應的第一個字節是「S」,則該消息被分類爲ParameterStatus消息。
在本節中它也表明,如果在服務器響應的第一個字節是「R」,則該消息被分類爲認證消息。
有用的資源,我發現:
我認爲這是可視化的消息流協議非常好的資源。作者姓名是Jan Urban滑雪。在幻燈片9上,顯示啓動數據包。我發現的唯一的東西(無論如何都是node.js)是需要有一個null結束符框之前。 。 。框。
https://www.pgcon.org/2014/schedule/attachments/330_postgres-for-the-wire.pdf