Exemple #1
0
 /**
  * Send an event to the client.
  * 
  * @param string $message The message payload to be sent.
  * @param string $event Type of the event.
  * 
  * @throws \InvalidArgumentException When the given message is not a valid UTF-8 string.
  */
 public function send(string $message, string $event = null) : Awaitable
 {
     if (!\preg_match('//u', $message)) {
         throw new \InvalidArgumentException('SSE messages must be encoded as UTF-8 strings');
     }
     $data = \str_replace("\n", "\ndata: ", $message);
     if ($event === null) {
         $event = '';
     } else {
         $event = "event: {$event}\n";
     }
     return $this->channel->send($event . "data: {$data}\n\n");
 }
Exemple #2
0
 protected function wireMapper(callable $map, Channel $input, int $concurrency = 1) : Channel
 {
     $output = new Channel($concurrency * 2);
     $executor = new Executor($concurrency);
     $closed = false;
     $count = 0;
     $n = 0;
     $job = null;
     $job = function () use(&$job, &$count, &$n, &$closed, $executor, $map, $input, $output) {
         try {
             if ($this->eof === ($val = (yield $input->receive($this->eof)))) {
                 if (--$count < 1) {
                     $output->close();
                 }
                 return;
             }
             $val = $map($val, $n++);
             if ($val instanceof \Generator) {
                 $val = (yield from $val);
             }
             if (!$closed) {
                 (yield $output->send($val));
                 $executor->execute($job);
             }
         } catch (\Throwable $e) {
             if (!$closed) {
                 $closed = true;
                 $output->close($e);
             }
         }
     };
     for ($i = 0; $i < $concurrency; $i++) {
         $count++;
         $executor->execute($job);
     }
     return $output;
 }
Exemple #3
0
 /**
  * Handle an FCGI STDIN record that transfers request body data.
  * 
  * @param Record $record
  * @param Channel $incoming
  */
 public function handleStdin(Record $record, Channel $incoming) : \Generator
 {
     if (!$this->received) {
         $this->received = true;
         $request = $this->buildRequest();
         $incoming->send([$this, $request]);
     }
     if ($record->data === '') {
         return $this->body->close();
     }
     return (yield $this->body->send($record->data));
 }
Exemple #4
0
 /**
  * Coroutine that parses incoming requests and queues them into the request pipeline.
  * 
  * @param DuplexStream $socket Stream being used to transmit HTTP messages.
  * @param Channel $pipeline HTTP request pipeline.
  * @param HttpRequest $request First HTTP request within the pipeline.
  */
 protected function parseIncomingRequests(HttpDriverContext $context, SocketStream $socket, Channel $pipeline, HttpRequest $request) : \Generator
 {
     try {
         do {
             $request = $request ?? (yield from $this->parseNextRequest($context, $socket));
             $close = $this->shouldConnectionBeClosed($request);
             (yield $pipeline->send([$request, $close]));
             (yield ((yield $request->getBody()->getReadableStream()))->getAwaitable());
             $request = null;
         } while (!$close);
         $pipeline->close();
     } catch (\Throwable $e) {
         $pipeline->close($e);
     }
 }