我必须连接具有异步套接字连接的远程服务器并检索数据。我可以连接,但有一个问题。
包裹是按件发送的。我有两个选择;我可以设置缓冲区并将整个包装整合在一起,或者在完成所有传输后组合碎片。我认为第一个选项(缓冲物)是正确的方法。
我定义了一个缓冲区大小,但它在第一部分不起作用。在其他部分,它的工作原理,但使用这种方法,我不能将整个包装整体,因为第一部分限制为5,24 Kb。
您可以在下面找到我的代码:
$loop = React\EventLoop\Factory::create();
$dnsResolverFactory = new React\Dns\Resolver\Factory();
$dns = $dnsResolverFactory->createCached('8.8.8.8', $loop);
$connector = new React\SocketClient\Connector($loop, $dns);
$connector->create( ENDPOINT_IP , ENDPOINT_PORT )->then(function (React\Stream\Stream $stream) use ($loop) {
$command = '{C:"EL",bmId:43,inst:"my_instance",tok:"my_token"}';
$command_length = strlen($command);
$command_length = pack("N", $command_length);
$stream->write($command_length);
$stream->write($command);
$stream->bufferSize = 999999;
$stream->on('data', function ($data) {
$package = substr($data, 0, 4);
$unpack = unpack('N', $package); // I'm getting whole package size
echo $data;
});
});
$loop->run();
我尝试在$stream->on('data', function ($data) {
行下定义一个缓冲区大小,但你猜它失败了。我不知道如何正确处理它。
提前致谢。
答案 0 :(得分:4)
“我可以设置一个缓冲区并将整个包装整合在一起,或者在完成所有传输后组合碎片。我认为第一个选项(缓冲物)是正确的方法。”
第一个选项是不,只是因为它不是套接字通信的工作方式。
如果您正在接收5 kB数据,并且您将缓冲区设置得足够大,那么假设10 kB,您不能指望在$stream->on('data', function ($data) { ...
的一次调用中您将获得全部5 kB。
你必须做三件事:
$stream->on('data', function ($data) { ...
时,有可能在两个块中收到1个然后3个字节。当连接数据的大小为>=4
时,则会读取消息的大小。好主意是你为循环设置了一个计时器,这样你就可以等待在有限的时间内收到整个消息。可能发生客户端和服务器之间的连接在传输过程中被破坏,如果您没有超时逻辑,您的循环将永远等待接收整个消息。