0

我想通过websocket 连接将二进制音频数据发送到 IBM watson STT 服务。我已成功建立连接,现在尝试以以下格式发送数据:

{
  "action":"start",
  "content-type": "audio/l16;rate=44100"
}
<binary audio data>
{
  "action":"stop"
}

为此:我正在读取一个原始音频文件(extn .pcm),如下所示

#include <string>
#include <fstream>

ifstream fin;
string binarydata, bdataline;

fin.open("/home/rohan/TestFile.pcm", ios::binary | ios::in);

while (fin) {
    // Read a Line from File
    getline(fin, bdataline);
    binarydata = binarydata + bdataline;
}

问题 1:我不确定我是否正确读取了二进制数据。应该是数据类型binarydatastring

接下来在boost websocket上发送数据(握手后)我遵循了这个例程

void on_handshake(beast::error_code ec)
    {
         if(ec)
             return fail(ec, "handshake");

         // Send the Start message
         ws_.async_write(net::buffer("{\"action\":\"start\",\"content-type\": \"audio/l16;rate=44100\"}"), bind(&session::on_start, shared_from_this(), placeholders::_1));
    }

void on_start(beast::error_code ec)
    {
        if(ec)
            return fail(ec, "write:start");

        ws_.async_write(net::buffer(binarydata), bind(&session::on_binarysent, shared_from_this(), placeholders::_1));
    }

void on_binarysent(beast::error_code ec)
    {
        if(ec)
            return fail(ec, "write:Msg");

        ws_.async_write(net::buffer("{\"action\":\"stop\"}"), bind(&session::on_write, shared_from_this(), placeholders::_1));
    }


void on_write( beast::error_code ec) //,
    {
        if(ec)
            return fail(ec, "write:end");

        ws_.async_read(buffer_, bind(&session::on_start, shared_from_this(), placeholders::_1));
    }

该程序不显示任何输出并退出

write:start:WebSocket 流在两个端点都正常关闭

问题 2:数据是否按预期正确运行?如何检查?(预计:见此链接

websocket如何在不发送关闭命令的情况下关闭?

更新:

void on_start(beast::error_code ec)
    {
        if(ec)
            return fail(ec, "write:start");



ifstream infile("/home/rohan/TestFile.pcm", ios::in | ios::binary);
    streampos FileSize;

    if (infile) {
        // Get the size of the file
        infile.seekg(0, ios::end);
        FileSize = infile.tellg();
        infile.seekg(0, ios::beg);
    }
    char binarydata[(size_t)FileSize];
        ws_.binary(true);

        // Send binary data
        ws_.async_write(net::buffer(binarydata, sizeof(binarydata)), bind(&session::on_binarysent, shared_from_this(), placeholders::_1));
    }
4

2 回答 2

2

答案1:

关于问题的 websocket 部分,您应该确保通过调用来发送二进制消息websocket::stream::binary(true)。看:

https://www.boost.org/doc/libs/1_69_0/libs/beast/doc/html/beast/ref/boost__beast__websocket__stream/binary/overload1.html

答案 2:

来自:https ://www.boost.org/doc/libs/1_69_0/libs/beast/doc/html/beast/using_websocket/control_frames.html#beast.using_websocket.control_frames.close_frames

“在读操作过程中收到关闭帧时,实现会自动以关闭帧响应,然后在返回之前关闭底层连接。在这种情况下,读操作将完成并显示代码错误::关闭。这表明向调用者表明连接已完全关闭。”

答案 3(更新)

你写了:

vector<char> binarydata(istreambuf_iterator<char {infile}, {});

您正在使用局部变量作为异步操作的缓冲区。调用者负责确保缓冲区的生命周期至少延长到调用完成处理程序。您的代码会产生未定义的行为。

Beast 文档清楚地说明了这一点:

“这个库是为熟悉 Boost.Asio 的程序员准备的。希望使用异步接口的用户应该已经知道如何使用回调或协程创建并发网络程序。”

https://www.boost.org/doc/libs/1_69_0/libs/beast/doc/html/beast/introduction.html

如果您还没有熟练使用 Asio,那么我建议您暂停当前项目并学习 Asio,以便您能够有效地使用 Beast。否则,您将在路径的每一步遇到障碍。

于 2018-12-26T13:22:51.833 回答
-1

您不能用于string存储二进制数据,不能使用char data[]with int lengthorstd::vector<char>或其他方式。

getline()一旦二进制文件中没有行,就不应立即读取二进制数据。

你可以使用类似的东西:

std::ifstream f("/home/rohan/TestFile.pcm", std::ios::binary);
std::vector<char> v(std::istreambuf_iterator<char>{f}, {});
于 2018-12-26T13:23:26.383 回答