public function handleWrite()
{
$error = null;
set_error_handler(function ($errno, $errstr, $errfile, $errline) use(&$error) {
$error = array('message' => $errstr, 'number' => $errno, 'file' => $errfile, 'line' => $errline);
});
$sent = fwrite($this->stream, $this->data);
restore_error_handler();
// Only report errors if *nothing* could be sent.
// Any hard (permanent) error will fail to send any data at all.
// Sending excessive amounts of data will only flush *some* data and then
// report a temporary error (EAGAIN) which we do not raise here in order
// to keep the stream open for further tries to write.
// Should this turn out to be a permanent error later, it will eventually
// send *nothing* and we can detect this.
if ($sent === 0 || $sent === false) {
if ($error === null) {
$error = new \RuntimeException('Send failed');
} else {
$error = new \ErrorException($error['message'], 0, $error['number'], $error['file'], $error['line']);
}
$this->emit('error', array(new \RuntimeException('Unable to write to stream: ' . $error->getMessage(), 0, $error), $this));
return;
}
$exceeded = isset($this->data[$this->softLimit - 1]);
$this->data = (string) substr($this->data, $sent);
// buffer has been above limit and is now below limit
if ($exceeded && !isset($this->data[$this->softLimit - 1])) {
$this->emit('drain', array($this));
}
// buffer is now completely empty (and not closed already)
if ($this->data === '' && $this->listening) {
$this->loop->removeWriteStream($this->stream);
$this->listening = false;
$this->emit('full-drain', array($this));
}
}