我正在尝试在数据库和其他节点项目之间建立中间人。 我意识到我的代码可能是垃圾,但是我正在做一个uni项目,并且有最后期限。

服务器代码:

const net = require('net'); const port = 7070; const host = '127.0.0.1'; const mariadb = require('mariadb/callback')  const conn = mariadb.createConnection({     host: 'localhost',     port: '3306',     user: 'root',     password: '',     database: 'ecomm' });  const server = net.createServer(); server.listen(port, host, () => {     console.log('API server is running on port ' + port + '.');     //console.log(conn);  });  let sockets = []; server.on('connection', function(sock) {     console.log('CONNECTED: ' + sock.remoteAddress + ':' + sock.remotePort);       sockets.push(sock);      sock.on('data', function(data) {         console.log('DATA ' + sock.remoteAddress + ': ' + data);         if (data == 'fetch') {             console.log("Fetch operation requested");             conn.query("SELECT item_id, item_name, item_price, held_by from items", (err, rows) => {                 if (err) console.log("DB connection failed: " + err);                 else {                     console.log(rows[0].item_price);                     //sock.write('hehe');                     var i;                     for (i = 0; i < 5; i++) {                         sock.write(JSON.stringify(rows[i]));                         //sock.write(rows[i]);                     }                  }             });         }         // Write the data back to all the connected, the client will receive it as data from the server      });      // Add a 'close' event handler to this instance of socket     sock.on('close', function(data) {         let index = sockets.findIndex(function(o) {             return o.remoteAddress === sock.remoteAddress && o.remotePort === sock.remotePort;         })         if (index !== -1) sockets.splice(index, 1);         console.log('CLOSED: ' + sock.remoteAddress + ' ' + sock.remotePort);     }); });  process.on('uncaughtException', function (err) {     console.error(err);     //console.log("Client disconnected");   }); 

客户代码:

const net = require('net'); const client = new net.Socket(); const port = 7070; const host = '127.0.0.1';   client.connect(port, host, function() {     console.log('API connection successful.');     client.write('fetch');  }); client.on('data', function(data) {     //console.log('Server Says : \n' + JSON.parse(data));     var parsed_data = JSON.parse(data);      console.log(parsed_data); });  client.on('close', function() {     console.log('Connection closed'); }); 

现在,服务器在收到提取请求后,将从数据库中获取所有项目,然后将其返回给客户端。 问题是,如果我发送1或2个项目; 它工作正常。 如果发送的内容超过此数量,则会出现解析错误,并且客户端崩溃。

    SyntaxError: Unexpected token { in JSON at position 64     at JSON.parse (<anonymous>)     at Socket.<anonymous> (C:\Users\saif\Desktop\CliServTest\client.js:14:2     at Socket.emit (events.js:198:13)     at addChunk (_stream_readable.js:288:12)     at readableAddChunk (_stream_readable.js:269:11)     at Socket.Readable.push (_stream_readable.js:224:10)     at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17) 

我已经尝试修复了几个小时,却一无所获。

===============>>#1 票数:0

客户端中的以下代码:

client.on('data', function(data) {     //console.log('Server Says : \n' + JSON.parse(data));     var parsed_data = JSON.parse(data);      console.log(parsed_data); }); 

是个问题。 TCP是一种流协议,不能保证您的数据到达什么块。在您发送的数据大小的某个点上(可能甚至取决于本地基础架构),您的数据将被分成多个块,并且将在单独的data事件中client.on('data', ...)到达client.on('data', ...) JSON格式无法分段解析。 在解析之前,您需要有整条JSON数据。

因此,您可能会得到部分JSON并尝试对其进行解析。


这通常是人们使用更高级别协议或更高级别库的主要原因之一,因为他们可以将您的所有数据块合并回发送的原始数据块,然后为您提供完整的数据块。 例如,webSocket将为您完成此任务。

因此,您必须编写一种能够从多个传入data事件中累积数据,将它们组合在一起,找出适当的JSON解析边界在何处,然后使用整个JSON调用JSON.parse()函数。

这意味着您可以将自己的标记放入可作为分隔符查找的TCP流中,发送一个长度,或者使用某种高级协议(例如webSocket)为您完成此操作。

以下是讨论一些选项的一些相关答案: 检测Node.js的Net模块中“数据”事件上接收到的完整数据,以及如何有效发送大数据包/合并较小的数据包?

如果您锁定了最快的编码解决方案,那么我可能会切换到使用webSocket而不是普通TCP,因为webSocket会为您提供一次发送的相同数据包。 它为您定界数据,累积传入的片段,将它们重组为最初发送的同一块,然后仅在整个块到达时才通知您。

  ask by saifxhatem translate from so

本文未有回复,本站智能推荐: