Coder Social home page Coder Social logo

Comments (10)

cboden avatar cboden commented on June 27, 2024 1

The PR didn't fully fix the problem. Pawl is being impatient beginning the shutdown process after sending its close frame before it has received the ack from the server. The node example doesn't like this. I'll need to do another PR with a timeout that will end the connection after sending in case the server doesn't sever the connection.

from pawl.

cboden avatar cboden commented on June 27, 2024

hmm, this is a little puzzling the fact that is happens with 2 different servers...

The logic is in fact in Pawl, not the RFC lib. 1006 is supposed to be issued if the underlying socket is closed without the upper WebSocket doing a closing handshake first...

  1. If you call close it will
  2. Call the inner close closure setting the static variable
  3. If the underlying socket closes we should call close abnormally
  4. The closure should ignore the call

--

As I was writing that I can see a scenario where this breaks: If the write happens in 1. and the server closes the connection (which is allowed at this point) 3. happens next causing 4. to happen before 2. ever happens.

However, with the above theory I wrote I would expect your var_dump($args) inside the on close would happen twice. Can you confirm this?

from pawl.

 avatar commented on June 27, 2024

No, the var_dump only happens once. However if I comment out the return statement inside the close closure, I do get two. The first one being code 1000 and the second one 1006, which is what I would expect, since the stream was closed, but since it was supposed to be a normal close, we ignore the abnormal close, hence the static variable and return statement.

from pawl.

cboden avatar cboden commented on June 27, 2024

I tried your node script and received the same result. I made a Ratchet server to contrast and received a 1002 when Pawl attempted to close.

Pawl close payload:
screen shot 2017-10-20 at 10 09 50 am

Ratchet response payload:
screen shot 2017-10-20 at 10 09 59 am

Pawl isn't masking its close frame. Oops!

from pawl.

cboden avatar cboden commented on June 27, 2024

From https://tools.ietf.org/html/rfc6455#section-7.1.1:

The underlying TCP connection, in most normal cases, SHOULD be closed
first by the server, so that it holds the TIME_WAIT state and not the
client (as this would prevent it from re-opening the connection for 2
maximum segment lifetimes (2MSL), while there is no corresponding
server impact as a TIME_WAIT connection is immediately reopened upon
a new SYN with a higher seq number). In abnormal cases (such as not
having received a TCP Close from the server after a reasonable amount
of time) a client MAY initiate the TCP Close. As such, when a server
is instructed to Close the WebSocket Connection it SHOULD initiate
a TCP Close immediately, and when a client is instructed to do the
same, it SHOULD wait for a TCP Close from the server.

I'll work on another PR to inject an EventLoop into WebSocket and only close the underlying TCP connection if the server hasn't done so after a protocol Close initiation after a period of time.

from pawl.

 avatar commented on June 27, 2024

The mentioned PR does work for Discord. ;)

from pawl.

cboden avatar cboden commented on June 27, 2024

v0.3.1 has been released with this fix

from pawl.

ryancwalsh avatar ryancwalsh commented on June 27, 2024

@cboden Thanks for ratchetphp/Pawl. Super impressive. And it's mostly working for me.

I'm using "ratchet/pawl": "^0.3.4", and I wonder if this issue is actually fixed or not. Above you said:

The PR didn't fully fix the problem. Pawl is being impatient beginning the shutdown process after sending its close frame before it has received the ack from the server. The node example doesn't like this. I'll need to do another PR with a timeout that will end the connection after sending in case the server doesn't sever the connection.

Do you think that's what I'm experiencing with this problem here?

Do you have any recommendations for me?

E.g. should I try #67 (comment)?

Thanks. I really appreciate your work.

from pawl.

ryancwalsh avatar ryancwalsh commented on June 27, 2024

@mbonneau You helped me solve this problem 21 days ago, and I really appreciate it.

I haven't been able to make progress since then. I'm still stuck getting a 1006 error code every time I send an mp3 larger than ~23 MB / 66 mins. (For shorter mp3s, it always works.)

I'm even following your advice to someone else and using addPeriodicTimer with PING.

    public function getTextFromAudio($audioFileContents, $contentType, $accessToken, $callback) {
        $this->listening = false;
        $this->responseJson = null;
        $url = \me\Tools\SystemTools::getUrlWithUpdatedParams(self::WS_HOST . self::WS_PATH, [
                    'model' => 'en-US_NarrowbandModel',
                    'watson-token' => $accessToken
                        ], \League\Uri\Ws::class);
        $headers = ['X-Watson-Learning-Opt-Out' => true];
        Log::debug('\Ratchet\Client\connect ' . sha1($audioFileContents));
        $loop = \React\EventLoop\Factory::create();
        $connector = new \Ratchet\Client\Connector($loop);
        $connector($url, [], $headers)->then(function(\Ratchet\Client\WebSocket $conn) use($contentType, $audioFileContents, $callback, $loop) {
            $conn->on('message', function($msg) use ($conn, $callback) {
                $this->handleIncomingWebSocketMessage($msg, $conn, $callback);
            });
            $conn->on('close', function($code = null, $reason = null) {
                Log::debug("Connection closed ({$code} - {$reason})");
            });
            $conn->on('error', function($error) {
                Log::error("Ratchet Pawl error ({$error})");
            });
            $loop->addPeriodicTimer(120, function () use ($conn) {
                $conn->send(new \Ratchet\RFC6455\Messaging\Frame('', true, \Ratchet\RFC6455\Messaging\Frame::OP_PING));
                Log::debug('sent ping');
            });
            $this->startWatsonStream($conn, $contentType);
            $this->sendBinaryMessage($conn, $audioFileContents);
            Log::debug('send action stop');
            $conn->send(json_encode(['action' => 'stop']));
        }, function (\Exception $e) use ($loop) {
            Log::error("Could not connect: {$e->getMessage()} " . $e->getTraceAsString());
            $loop->stop();
        });
        $loop->run();
    }

If my understanding is correct that 1006 is always a client-side issue, it means that I'm not properly using ratchetphp/Pawl.

I'm wondering if you see anything that I'm doing wrong.

What would you look into?

I really appreciate all of your help!

from pawl.

hobsRKM avatar hobsRKM commented on June 27, 2024

v0.3.1 has been released with this fix

it's not fixed. I am still getting this error in the latest version 0.3.5. I am not calling close explicitly, but after keeping it alive for about 3-4 hours socket gets closed with 1006.

from pawl.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.