php - NodeJS 从 PHP 服务器接收数据

标签 php sockets node.js

我目前正在开发一个简单的 NodeJS 客户端,它使用网络类连接到 PHP 服务器。另外,NodeJS客户端作为Socket.IO服务器,将从PHP服务器接收到的数据发送到与Socket.IO连接的浏览器。

到目前为止,一切正常。然而,如果我与另一个客户端连接到 Socket.IO,PHP 服务器必须向每个连接的客户端发送通知。因此,它将一个 JSON 编码的数组发送到处理 JSON 数据的 NodeJS 客户端(对其进行解码和修改)。

现在的问题是,有时 PHP 服务器发送的两条单独的消息会在 NodeJS 的 onData 事件处理函数中连接起来:

client.on("data", function(data) {

   var msgData = JSON.parse(data.toString("utf8"));
   [...]
}

变量data现在有时(不是每次!)包含两个 JSON 字符串,例如:

 { "todo":"message", [...] } { "todo":"message", [...] }

这当然会导致 JSON.parse 函数抛出异常。我预计 onData 函数的两次调用,变量 data 为:

{ "todo":"message", [...] }

在 PHP 服务器端,我必须迭代包含当前提供的所有 Socket.IO 连接的数组:

foreach($sockets as $id => $client) {

    $nodeJS->sendData($client, array("todo" => "message", [...]);
}

$nodeJS->sendData函数对数组进行 json 编码并将其发送到 NodeJS 客户端:

socket_write($nodeClient, json_encode($dataToSend));

$nodeJS->sendData函数最终被调用两次,就像socket_write一样。

我现在不知道是 PHP 还是 NodeJS 连接这两个字符串。我想要的是,每次调用 $nodeJS->sendData 函数时,NodeJS 都会调用 onData-handler 一次(例如,sendData 被调用两次 → onData-event 被触发两次)。 当然,我可以在每个 json 编码字符串的末尾添加一些标志,然后在 onData 函数中将它们拆分为一个数组。但是,我不太喜欢这个解决方案。

有没有更简单的方法来实现这一点?

最佳答案

重要的是要记住,当您从套接字读取数据时,数据将以任意 block 的形式出现,并且完全取决于您的代码将它们分割成对处理有意义的单元;绝对不能保证每个 block 都会对应一个有意义的单元。

yannisgu 已经为您提供了解决方案的第一部分(用换行符终止每个单元,这样您的代码就可以知道它在哪里结束):现在您需要实现第二部分,即缓冲传入的数据并将其拆分转换为单位。

在初始化时,执行类似的操作

var buf = '';

并将客户端的编码设置为utf8。

在您的“data”处理程序中: [更新:纳入 josh3736 的建议]

buf += data;
var idx;
while ((idx = buf.indexOf('\n')) >= 0) {
   // there's at least one complete unit buffered up
   var unit = buf.slice(0, idx);
   // extract it
   if (unit.slice(-1) == '\r') {
     // CRLF delimited
     unit = unit.slice(0, -1);
   }
   if (unit.length) {
     // ignore empty strings
     var msgData = JSON.parse(unit);
     [...]
     // process it
   }
   buf = buf.slice(idx +1);
   // discard it
}
// at this point, buf is either empty or contains an incomplete
// unit which will be processed as soon as the rest of it comes in

关于php - NodeJS 从 PHP 服务器接收数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12071780/

相关文章:

php - 为什么php字符串中都是单字

perl - 如何在 Perl 中使用原始套接字?

php - 在 PHP Mailer 中发送多封邮件

c - 套接字 UDP : Using Sender Info from Recvfrom() in Sendto() Fails

java - (Java) 套接字的 BufferedReader 一次仅读取一行,在接收下一行之前需要客户端输入

javascript - NodeJS : Functional Programming - No access to prototype in handover function

javascript - 在 Node exec 回调响应中无法正常工作

node.js - Socket.io 1.0,IE7。无法读取发出的消息

mysql - 从备份中恢复 Magento 静态 block 内容?

php - 在 Laravel 数据表中添加 HTML 属性