Skip to content
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

tryUnpack - how do you know when to return while streaming #19

Closed
decebal opened this issue Feb 20, 2018 · 2 comments
Closed

tryUnpack - how do you know when to return while streaming #19

decebal opened this issue Feb 20, 2018 · 2 comments

Comments

@decebal
Copy link

decebal commented Feb 20, 2018

When reading from an open socket how do you know if you read all the bits and pieces of the packed message so that you should return the data.
I am looking for a mechanism to replace streaming like this: msgpack-php extension

Here is what I tried, but it only ends in a loop that never returns, I need a stop, a way of knowing when the message is complete:

         stream_set_blocking($io, 0);
         $unpackedBlocks = null;
         $unpacker = new BufferUnpacker();

        while (!feof($io)) {
            $r = array($io);
            $n = null;
            stream_select($r, $n, $n, null);
            $read = fread($io, $size);
            if ($read === false) {
                throw new MessagePackRPCNetworkException(error_get_last());
            }
            $unpacker->append($read);
            $unpackedBlocks = $unpacker->tryUnpack();
        }

        return $unpackedBlocks;
@rybakit
Copy link
Owner

rybakit commented Feb 20, 2018

A non-empty result of the $unpacker->tryUnpack() call indicates that the entire msgpack message (or several) has been received and unpacked. If you expect only one message from a stream, you can just do:

if ($unpackedBlocks = $unpacker->tryUnpack()) {
    return $unpackedBlocks[0];
}

If you receive an unknown number of msgpack messages from the stream, then I guess feof() is the right way to break the loop.

@decebal
Copy link
Author

decebal commented Feb 20, 2018

that was so simple, I can't believe I didn't figure that out. I was trying to compare the lengths somehow..
Here's my snippet now:

         stream_set_blocking($io, 0);
         $unpackedBlocks = null;
         $unpacker = new BufferUnpacker();

        while (!feof($io)) {
            $r = array($io);
            $n = null;
            stream_select($r, $n, $n, null);
            $read = fread($io, $size);
            if ($read === false) {
                throw new MessagePackRPCNetworkException(error_get_last());
            }
            $unpacker->append($read);
            $unpackedBlocks = $unpacker->tryUnpack();
            if ($unpackedBlocks) {
                  return $unpackedBlocks;
            }
        }

        throw new RPCNetworkException("Could not read the server response!");

Also this allows me to process multiple messages at once!

@decebal decebal closed this as completed Feb 20, 2018
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