Skip to content

Writing large string error #155

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
giuseppedevito opened this issue Mar 28, 2023 · 2 comments
Closed

Writing large string error #155

giuseppedevito opened this issue Mar 28, 2023 · 2 comments

Comments

@giuseppedevito
Copy link

giuseppedevito commented Mar 28, 2023

I think there is a bug at line 1150 of MqttClient class:

client/src/MqttClient.php

Lines 1141 to 1171 in 0847abe

protected function writeToSocket(string $data, int $length = null): void
{
$calculatedLength = strlen($data);
$length = min($length ?? $calculatedLength, $calculatedLength);
if ($this->settings->shouldUseBlockingSocket()) {
socket_set_blocking($this->socket, true);
}
$result = @fwrite($this->socket, $data, $length);
if ($this->settings->shouldUseBlockingSocket()) {
socket_set_blocking($this->socket, false);
}
if ($result === false || $result !== $length) {
$this->logger->error('Sending data over the socket to the broker failed.');
throw new DataTransferException(
DataTransferException::EXCEPTION_TX_DATA,
'Sending data over the socket failed. Has it been closed?'
);
}
$this->bytesSent += $length;
$this->logger->debug('Sent data over the socket: {data}', ['data' => $data]);
// After writing successfully to the socket, the broker should have received a new message from us.
// Because we only need to send a ping if no other messages are delivered, we can safely reset the ping timer.
$this->lastPingAt = microtime(true);
}

This will result in DataTransferException event with messages over 100 KB (MQTT has a maximum allowed message size of 256 MB).

I solved the issue adding the method:

protected function writeChunks($fp, $string) {
    $fwrite = 0;
    for ($written = 0; $written < strlen($string); $written += $fwrite) {
        $fwrite = @fwrite($fp, substr($string, $written));
        if ($fwrite === false) {
            return $written;
        }
    }
    return $written;
}

and changing line 1150 to:

$result = $this->writeChunks($this->socket, $data);

With this update your code is working fine.

@Namoshek
Copy link
Collaborator

A detailed analysis and a possible solution regarding this issue can be found in #133.

@giuseppedevito
Copy link
Author

Tanks for your fast reply @Namoshek ... #133 closes this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants