-
Notifications
You must be signed in to change notification settings - Fork 73
Data read from socket doesn't match expected length #95
Description
Hello!
I've been using Hoa\Websocket to interface with Chromium's debugging protocol in order to print PDFs. Chromium returns the PDF data in the response as a base64-encoded string, which can grow quite long (several MiB). I found that the response that i was getting back was the wrong size, usually severely truncated (tens of KiB).
To rule out an issue with Chromium, i created a server.php that simply sends 5 MB of base64-encoded garbage back to the client on connect, and i made a client.php to just print the length of the bucket message it receives. This is my result:
~ % php server.php &
[1] 5224
~ % php client.php
server: Sending 5000000 bytes
client: Received 22390 bytes
~ % php client.php
server: Sending 5000000 bytes
client: Received 22390 bytes
~ % php client.php
server: Sending 5000000 bytes
client: Received 22390 bytes
~ % php client.php
server: Sending 5000000 bytes
client: Received 1749065 bytes
~ % php client.php
server: Sending 5000000 bytes
client: Received 789220 bytes
~ % php client.php
server: Sending 5000000 bytes
client: Received 789220 bytes
~ % php client.php
server: Sending 5000000 bytes
client: Received 4411468 bytes
Ultimately the issue seems to lie in the call to stream_socket_recvfrom() within Hoa\Socket\Connection\Connection::read(). I've confirmed that it receives the correct $length, but the result never matches it.
I'm creating the issue here rather than under Hoa\Socket because i'm assuming this has something to do with blocking or buffering settings rather than any flaw in the read() method itself... but i'm not sure. Am i doing something wrong?
Code to replicate:
server.php
<?php
require_once __DIR__ . '/vendor/autoload.php';
use Hoa\Event;
use Hoa\Socket;
use Hoa\Websocket;
$bytes = $argv[1] ?? 5000000;
$server = new Websocket\Server(new Socket\Server('ws://127.0.0.1:8889'));
$server->on('open', function (Event\Bucket $bucket) use ($bytes) {
$data = substr(base64_encode(random_bytes($bytes)), 0, $bytes);
printf("server: Sending %d bytes\n", strlen($data));
$bucket->getSource()->send($data);
});
$server->run();
client.php
<?php
require_once __DIR__ . '/vendor/autoload.php';
use Hoa\Event;
use Hoa\Socket;
use Hoa\Websocket;
$client = new Websocket\Client(new Socket\Client('ws://127.0.0.1:8889'));
$client->on('message', function (Event\Bucket $bucket) {
printf("client: Received %d bytes\n", strlen($bucket->getData()['message']));
});
$client->setHost('127.0.0.1');
$client->connect();
$client->receive();