Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
NodeJS从PHP服务器接收数据_Php_Sockets_Node.js - Fatal编程技术网

NodeJS从PHP服务器接收数据

NodeJS从PHP服务器接收数据,php,sockets,node.js,Php,Sockets,Node.js,我目前正在开发一个简单的NodeJS客户端,它使用net类连接到PHP服务器。此外,NodeJS客户端作为Socket.IO服务器工作,它将从PHP服务器接收的数据发送到与Socket.IO连接的浏览器 到目前为止,一切正常。但是,如果我与另一个客户机连接到Socket.IO,PHP服务器必须向每个连接的客户机发送通知。因此,它向处理JSON数据的NodeJS客户端发送一个JSON编码的数组(稍微解码和修改它) 现在的问题是,有时PHP服务器发送的两条单独的消息在NodeJS的onData事件处

我目前正在开发一个简单的NodeJS客户端,它使用net类连接到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"));
   [...]
}
变量数据现在有时(不是每次!)包含两个JSON字符串,例如:

 { "todo":"message", [...] } { "todo":"message", [...] }
这当然会导致JSON.parse函数引发异常。我期望两次调用onData函数,变量数据为:

在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\u write一样

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


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

尝试在PHP端的JSON字符串后添加新行

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

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

在初始化时,执行如下操作

var buf = '';
并将
客户端的编码设置为utf8

在您的
“数据”
处理程序中: [更新:3736的建议]

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

例如
socket\u write($nodeClient,json\u encode($dataToSend)。“\n”)
?同时尝试了\n和\r\n-不幸的是,这并没有解决问题。+1;这是处理流中数据的正确方法。为了完整性起见,我只想添加一些额外的检查来处理
CRLF
换行符(而不仅仅是
LF
),以及处理空行(
JSON.parse
如果给它一个零长度字符串,就会抛出)。我不久前写过这样的东西。
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