Skip to content

Instantly share code, notes, and snippets.

@exodus4d
Created February 17, 2019 13:20
Show Gist options
  • Save exodus4d/558fa0e4314cb6c497692ada46c3d8ec to your computer and use it in GitHub Desktop.
Save exodus4d/558fa0e4314cb6c497692ada46c3d8ec to your computer and use it in GitHub Desktop.
reactphp NDJSON client decoder
<?php
// NDJSON Ping/Pong communication:
// 1. Client send ONE JSON object
// 2. Server respond with ONE JSON obect
// 3. Client MIGHT send another JSON object
// 4. Server WOULD respond with OND JSON object
// 5. ....
// Questions:
// [1] I use first() in combination with once(), because a data chunk MIGHT contain multiple NDJSON objects
// 2nd, 3rd object should be ignored... Is this a good practice?
// [2] Is it good practice to use once() rather than on() to "ignore" future data?
// I reuse function in case of 2nd, 3rd,.. ping->pong call
function(Socket\ConnectionInterface $connection) : Promise\PromiseInterface {
// new empty (temp) stream for processing
$stream = new Stream\ThroughStream();
// ... new JSON decoded stream
$streamDecoded = new Clue\React\NDJson\Decoder($stream);
// promise get resolved on first emit('data') [1]
$promise = Promise\Stream\first($streamDecoded);
// register on('data') for main input stream [2]
$connection->once('data', function ($chunk) use ($stream) {
// send current data chunk to processing stream -> resolves promise
$stream->emit('data', [$chunk]);
});
return $promise;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment