Comments (10)
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.
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...
- If you call close it will
- Call the inner close closure setting the static variable
- If the underlying socket closes we should call close abnormally
- 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.
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.
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 isn't masking its close frame. Oops!
from pawl.
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.
The mentioned PR does work for Discord. ;)
from pawl.
v0.3.1 has been released with this fix
from pawl.
@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.
@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.
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)
- Connection closed (4005 - Already authenticated.) HOT 1
- underlying connection closed 1006 HOT 1
- Allow guzzlehttp/psr7 v2 HOT 1
- Call to undefined function GuzzleHttp\Psr7\uri_for() HOT 3
- Call to undefined function GuzzleHttp\Psr7\uri_for() HOT 6
- How to send command line live output to websocket server?
- send variable HOT 2
- Implementation to listen for socket.io events
- Sending binary messages refuse to work with specific char suite. HOT 2
- Cannot get TLS to work on proxied websocket with nginx
- Question - RabbitMq consumer freezing the websocket HOT 4
- How to authenticate with PEM certificate? HOT 2
- send message from php to websocket HOT 1
- reconnect to server when internet connection has been intrupted
- Message lost on 2 separate connections to same URL HOT 1
- PHP Warning: stream_select(): You MUST recompile PHP with a larger value of FD_SETSIZE.
- Unhandled promise rejection with DomainException: HTTP/1.1 200 OK
- Uncaught UnderflowException: Frame
- conflict with laravel-websockets HOT 1
- Immediately send and submit to the server.
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from pawl.