【发布时间】:2019-03-18 14:47:51
【问题描述】:
我正在使用 Ratchet 连接到 IBM Watson websockets,它似乎总是适用于较小的文件(我已经测试了长达 66 分钟的 23 MB mp3 文件),但它总是失败较大的文件(例如 2 小时 56 MB 的 mp3)。
这是我的日志:
[2019-03-17 21:43:23] local.DEBUG: \Ratchet\Client\connect bf4e38983775f6e53b392666138b5a3a50e9c9c8
[2019-03-17 21:43:24] local.DEBUG: startWatsonStream options = {"content-type":"audio\/mpeg","timestamps":true,"speaker_labels":true,"smart_formatting":true,"inactivity_timeout":-1,"interim_results":false,"max_alternatives":1,"word_confidence":false,"action":"start"}
[2019-03-17 21:43:24] local.DEBUG: Split audio into this many frames: 570222
[2019-03-17 21:43:42] local.DEBUG: send action stop
[2019-03-17 21:43:42] local.DEBUG: Received: {
"state": "listening"
}
[2019-03-17 21:43:42] local.DEBUG: Received first 'listening' message.
[2019-03-17 22:56:31] local.DEBUG: Connection closed (1006 - Underlying connection closed)
请注意接收到第一个“正在侦听”消息之间的 1 小时 13 分钟,然后连接因错误而关闭。
Watson说:“1006表示连接异常关闭。”
https://www.rfc-editor.org/rfc/rfc6455 说:
1006 是一个保留值,绝不能被端点设置为关闭控制帧中的状态码。它被指定用于期望状态代码指示连接已异常关闭的应用程序,例如,没有发送或接收关闭控制帧。
我可以调整我的代码的哪一部分,以便它可以处理更长的 mp3 文件而不会引发 1006 错误?
\Ratchet\Client\connect($url, [], $headers)->then(function(\Ratchet\Client\WebSocket $conn) use($contentType, $audioFileContents, $callback) {
$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})");
});
$this->startWatsonStream($conn, $contentType);
$this->sendBinaryMessage($conn, $audioFileContents);
Log::debug('send action stop');
$conn->send(json_encode(['action' => 'stop']));
}, function (\Exception $e) {
Log::error("Could not connect: {$e->getMessage()} " . $e->getTraceAsString());
});
...
public function handleIncomingWebSocketMessage($msg, $conn, $callback) {
Log::debug("Received: " . str_limit($msg, 100));
$msgArray = json_decode($msg, true);
$state = $msgArray['state'] ?? null;
if ($state == 'listening') {
if ($this->listening) {//then this is the 2nd time listening, which means audio processing has finished and has already been sent by server and received by this client.
Log::debug("FINAL RESPONSE: " . str_limit($this->responseJson, 500));
$conn->close(\Ratchet\RFC6455\Messaging\Frame::CLOSE_NORMAL, 'Finished.');
$callback($this->responseJson);
} else {
$this->listening = true;
Log::debug("Received first 'listening' message.");
}
} else {
$this->responseJson = $msg;
}
}
public function sendBinaryMessage($conn, $fileContents) {
$chunkSizeInBytes = 100; //probably just needs to be <= 4 MB according to Watson's rules
$chunks = str_split($fileContents, $chunkSizeInBytes);
Log::debug('Split audio into this many frames: ' . count($chunks));
$final = true;
foreach ($chunks as $key => $chunk) {
$frame = new \Ratchet\RFC6455\Messaging\Frame($chunk, $final, \Ratchet\RFC6455\Messaging\Frame::OP_BINARY);
$conn->send($frame);
}
}
【问题讨论】:
-
我猜想在
$conn->on('close',上你会想要重新建立连接。 -
@chughts 我很好奇为什么较小的文件可以工作。我的理解是,会话有可能(甚至可能需要?)一直保持打开状态,直到所有处理完成并且我的客户收到整个响应。例如。 “在发送最后一个块以指示流结束后,您无需担心会话超时。服务会继续处理音频,直到返回最终的转录结果。当您转录较长的音频流时,.. .
-
@chughts "...服务可能需要超过 30 秒的时间来处理音频并生成响应。服务在完成处理它拥有的所有音频之前不会开始计算会话超时已收到。服务的处理时间不会导致会话超过 30 秒的会话超时。 - cloud.ibm.com/docs/services/…
-
我猜这不是关闭 Web 套接字的服务,而是自动关闭它的底层 Web 套接字基础设施。
-
@chughts 啊,所以你的意思是我的 PHP 服务器(它作为 websockets 的 client 使用)使用 Ratchet 库。 stackoverflow.com/a/19305172/470749 同样表示 1006 是由客户端而不是 websockets 服务器引起的错误。我还不确定要调查什么,但听说这可能是 我的 端(并且在我的控制范围内)而不是 IBM 端的事情是令人鼓舞的。我想至少我可以试试你重新连接的想法。谢谢。
标签: websocket ibm-watson ratchet