NodeJS从PHP服务器接收数据

时间:2012-08-22 11:09:45

标签: php sockets node.js

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

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

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

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

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

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

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

这当然会导致 JSON.parse 函数抛出异常。我期望对变量 data 的onData函数进行两次调用:

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

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

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

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

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

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

$ em> $ nodeJS-> sendData 函数最终被调用两次,因为socket_write是。

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

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

2 个答案:

答案 0 :(得分:4)

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

yannisgu已经为您提供了解决方案的第一部分(使用换行符终止每个单元,因此您的代码可以告诉它结束的位置):现在您需要实现第二部分,即缓冲传入的数据并将其拆分成单位。

在初始化时,执行类似

的操作
var buf = '';

并将client的编码设置为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

答案 1 :(得分:1)

尝试在PHP端的JSON-String之后添加一个新行。