我的目标是将套接字连接(一旦“握手”(http 升级)和“身份验证”(我自己的函数使用提供的详细信息对我的数据库进行挑战))传递给另一个 php 脚本进程(未分叉),以便它可以将其添加到自己的套接字资源“经过身份验证的客户端”数组中并接管连接。一旦它通过 sendmsg 的 php 包装器发送(socket_sendmsg - 谁的 PHP 文档不准确,所以我一直在看人们试图在 c 中做同样的事情)
如果我发送:
socket_sendmsg($hsSocket, ["iov" => [json_encode(array('action'=>'add','uID'=>$messageObj->uID,'uDatID'=>$messageObj->uDatID,'sessID'=>$messageObj->sessID))], "control" => [["level" => SOL_SOCKET, "type" => SCM_RIGHTS, "data" => [$authlogfd]]]], 0);
如果我这样做(在该resourceArray上的socket_select之后),它正在发送打开的日志文件的文件描述符:
if(socket_recvmsg($arrayOfSocketResources, $hsSocketData,MSG_DONTWAIT)){
printf("SS:HS: got recvmsg control data\n");
print_r($hsSocketData);
if(isset($hsSocketData['control'][0]['data'][0])){
$newlogfd=$hsSocketData['control'][0]['data'][0];
$msg=json_decode($hsSocketData['iov'][0],true);
if(isset($msg['action'])&&$msg['action']=='add'){
$sendmsg=PHP_EOL."from second script".PHP_EOL;
fwrite($newlogfd,$sendmsg,strlen($sendmsg));
printf("SS:HS: got descriptor %s action:%s uID:%s uDatID:%s sessID:%s\n",$newlogfd,$msg['action'],$msg['uID'],$msg['uDatID'],$msg['sessID']);
}
然后我在日志中看到“来自第二个脚本”的消息(所以我能够写入传递的文件描述符 - 即使在传递者关闭之后(每个进程都有一个计数附加到文件描述或某些东西会增加))。如果我从传递者而不是日志文件描述符发送它,这也适用于 STDOUT。
当我更改为发送一个经过身份验证的 tcp 套接字客户端资源时,如果我转储它会显示一个资源 ID:
Array(
[name] =>
[control] => Array
([0] => Array
(
[level] => 1
[type] => 1
[data] => Array
(
[0] => Resource id #12
)
)
)
[iov] => Array
(
[0] => {"action":"add","uID":"816-2554846393-11","uDatID":"fe1eba892f2144b3c9ce49f79c7a8386","sessID":"9mpr38o5nrmqke0mfejvn3801l"}
)
[flags] => 0
)
问题是当我尝试使用传递的套接字资源“Resource id #12”时,我得到
socket_send(): supplied resource is not a valid Socket
在其读取资源数组中添加了“Resource id #12”的 socket_select 也抱怨它无效。
我在这里尝试以某种不同的方式传递套接字吗?我错过了什么(除了显而易见的事情)。