elephant.io icon indicating copy to clipboard operation
elephant.io copied to clipboard

Read function

Open marshhxx opened this issue 11 years ago • 7 comments

Hi I am having problems when reading a message from the server. My server is based on netty-socketio and the way I send messages to a client is: this.client.sendEvent("serverMessage",message); The messages are encrypted. As you can see netty-socketio is orientated to events. The issue I am experiencing is that for example if I send "75559" I read 42["serverMessage","7 . I am not reading the entire message and also I am reading the event name I use to send messages from netty-socketio to elephant.io. Do you know why I am not reading the entire message? Thanks

marshhxx avatar Sep 17 '14 19:09 marshhxx

Now I am sending the message from server like this "this.client.send(message);" but I am still not reading the whole message .., any idea why I cannot read properly?

marshhxx avatar Sep 17 '14 22:09 marshhxx

Hey @jrdiaz your function "read" has saved my life. I am using your function but instead of returning $payload I am returning [ return (string) new Decoder($payload); ] and now I am reading the entire payload. Thank you very much !!! :)

marshhxx avatar Sep 18 '14 16:09 marshhxx

I'm glad it helped you! :D :D

jrdiaz avatar Sep 18 '14 17:09 jrdiaz

Hi,

I'm sorry, but the read method is more a POC than a functionnal feature (as it was adapted from the old legacy code, without any tests as we don't really need it here at wisembly...). But as you managed to make it work, could you share what you did (through a PR, a gist, ...), so we may enhance the current read method ? Thanks !

Taluu avatar Sep 18 '14 18:09 Taluu

Hi @Taluu

This is the code I'm using:

<?php
// ...
    public function read() {
               // Ignore first byte, I hope Socket.io does not send fragmented frames, so we don't have to deal with FIN bit.
                // There are also reserved bit's which are 0 in socket.io, and opcode, which is always "text frame" in Socket.io
                $header  = fread($this->stream, 1);
                // There is also masking bit, as MSB, but it's 0 in current Socket.io
                $payload_len = ord(fread($this->stream, 1));

                switch ($payload_len) {
                        case 126:
                                $payload_len = unpack("n", fread($this->stream, 2));
                                $payload_len = $payload_len[1];
                                break;
                        case 127:
                                break;
                }
                // Reads the socket until full data is read
                //$payload = fread($this->fd, $payload_len); // Does not works if packet size > 16Kb
                $payload = '';
                $read    = 0;
                while( $read < $payload_len && ( $buf = fread( $this->stream, $payload_len - $read ) ) )
                {
                        $read    += strlen($buf);
                        $payload .= $buf;
                }
                 // decode the payload
                return (string) new Decoder($payload);
        }

I have not tested what happens if payload length is 127 or what happens with if (true === $mask) that's why I am not doing a PR. I am sure this method is reading the whole stream. Anyway if you want me to do a pull request let me know, I can do it. Hope it helps.

marshhxx avatar Sep 18 '14 21:09 marshhxx

Thanks @marshhxx, indeed, read() function needs replacement or fix. Here is a test I ran against simple socket.io server with socket.broadcast.emit('push', msg);. Note two $client2->read() calls

function testBroadcast() {
    $client = new Client(new Version1X('https://localhost:3000'));
    $client2 = new Client(new Version1X('https://localhost:3000'));
    $client2->initialize();
    $client->initialize();

    $client2->read();
    $client->emit('message', ["integration testing socketIO"]);
    $r = $client2->read();
    $client->close();
    $client2->close();

    $this->assertEquals('["push",["integration testing socketIO"]]', $r);
}

tot-ra avatar Oct 31 '14 09:10 tot-ra

Hi, Thank you @marshhxx

This is a very useful function. I have just added one thing at the beginning : if (!is_resource($this->stream)) {return;}

As I want to parse the response, I had some problems with the Decoder in the return so I don't decode the payload.

titouan13 avatar Dec 27 '14 17:12 titouan13