问题
I'm excited to be using Pawl, and I have it working for small files (such as 350 KB).
However, when I send a larger file (say, 30 MB) via $fullFileName
as shown below, I get this error: Connection closed (1009 - )
.
\Ratchet\Client\connect($url)->then(function(\Ratchet\Client\WebSocket $conn) use($contentType, $fullFileName) {
$conn->on('message', function($msg) use ($conn) {
Log::debug("Received: {$msg}");
});
$conn->on('close', function($code = null, $reason = null) {
Log::debug("Connection closed ({$code} - {$reason})");
});
$conn->send(json_encode([
'content-type' => $contentType,
'timestamps' => true,
'speaker_labels' => true,
'smart_formatting' => true,
'inactivity_timeout' => 60 * 5,
'x-watson-learning-opt-out' => true,
'action' => 'start'
]));
$frame = new \Ratchet\RFC6455\Messaging\Frame(file_get_contents($fullFileName), true, \Ratchet\RFC6455\Messaging\Frame::OP_BINARY);
$binaryMsg = new \Ratchet\RFC6455\Messaging\Message();
$binaryMsg->addFrame($frame);
$conn->send($binaryMsg);
$conn->send(json_encode([
'action' => 'stop'
]));
}, function ($e) {
echo "Could not connect: {$e->getMessage()}\n";
});
When I search for usages of Frame::CLOSE_TOO_BIG
, I see that it's only ever used by \Ratchet\RFC6455\Messaging\CloseFrameChecker
.
But I've been unable to figure out how \Ratchet\RFC6455\Messaging\CloseFrameChecker
works and what the file size limits are and how to send large files.
I've tried first splitting my file into chunks using str_split
and then adding individual frames, but then I hit session timeouts every time, even for small files.
What is the appropriate way to send larger files, avoiding the Frame::CLOSE_TOO_BIG
1009 error and session timeouts?
回答1:
https://cloud.ibm.com/apidocs/speech-to-text and https://cloud.ibm.com/docs/services/speech-to-text?topic=speech-to-text-websockets#WSreturn say 1009 = The connection closed because the frame size exceeded the 4 MB limit.
So I tried splitting the audio file into separate frames. My first attempts always resulted in a "Session timed out."
error.
https://cloud.ibm.com/docs/services/speech-to-text?topic=speech-to-text-input#timeouts says:
You do not need to worry about the session timeout after you send the last chunk to indicate the end of the stream. The service continues to process the audio until it returns the final transcription results. When you transcribe a long audio stream, the service can take more than 30 seconds to process the audio and generate a response. The service does not begin to calculate the session timeout until it finishes processing all audio that it has received. The service's processing time cannot cause the session to exceed the 30-second session timeout.
Here is the code that seems to work for me:
/**
* @param \Ratchet\Client\WebSocket $conn
* @param string $fileContents
*/
public function sendBinaryMessage($conn, $fileContents) {
$chunks = str_split($fileContents, 100);
Log::debug('Split audio into this many frames: ' . count($chunks));
$final = true;
foreach ($chunks as $key => $chunk) {
Log::debug('send chunk key ' . $key);
$frame = new \Ratchet\RFC6455\Messaging\Frame($chunk, $final, \Ratchet\RFC6455\Messaging\Frame::OP_BINARY);
$conn->send($frame);
}
}
来源:https://stackoverflow.com/questions/55082401/ratchetphp-pawl-connection-closed-1009-frameclose-too-big-1009