通过Beast Websocket发送连续数据块时,找不到“ Broken Pipe”错误的原因

时间:2019-03-29 13:15:58

标签: c++ boost websocket boost-beast beast

我正在使用IBM Watson语音对文本Web服务API进行流音频识别。我用C ++(std 11)创建了一个带有boost (beast 1.68.0)库的网络套接字。

我已成功连接到IBM服务器,并希望通过以下方式将 231,296字节原始音频数据发送到服务器。

[MyProject/build]$ cmake ..
[MyProject/build]$ make

IBMServer的预期结果是:

[MyProject/build]$ cmake ..
[MyProject/build]$ cmake --build . --target target1 -- -j 12
  

但是我没有得到想要的结果:相反,错误提示   “破损的管道”

$UncPath = 'E:\temp\test'

$all = Get-Acl $UncPath |
            Select -ExpandProperty Access |
            Where-Object { (-not $_.IsInherited) -and ('NT AUTHORITY\SYSTEM','BUILTIN\Administrators','CREATOR OWNER' -notcontains $_.IdentityReference) } |
            Select-Object @{ Name = 'Identity'; Expression = { $_.IdentityReference -replace "\w+\\(.+)", '$1' } }, FileSystemRights

# Here you can get Users ACL
$distinct_users = $all | 
            Select-Object Identity, @{ Name = 'sAMAccountName'; Expression = { (Get-ADUser -Identity $_.Identity -ErrorAction SilentlyContinue).sAMAccountName }}, FileSystemRights |
            Where-Object sAMAccountName -ne $null
# Here we will expand group acls
 $groups = $all | 
            Select-Object Identity, @{ Name = 'sAMAccountName'; Expression = { (Get-ADGroup -Identity $_.Identity -ErrorAction SilentlyContinue).sAMAccountName }}, FileSystemRights |
            Where-Object sAMAccountName -ne $null            
# now we will get groups memebership
$group_users = @()
Foreach($group in $groups){
    Get-ADGroupMember -Identity $group.Identity | ForEach-Object { $group_users += [PSCustomObject]@{ 
                                                                                        'Identity' = $group.Identity
                                                                                        'sAMAccountName' = $_.sAMAccountName
                                                                                        'FileSystemRights' = $group.FileSystemRights
                                                                                    } }

}

$everyone = $distinct_users + $group_users
$everyone | Export-Csv -Path D:\example.csv
  

这是我的代码,它是野兽库中给出的sample example的改编。

Foo.hpp

{
  "action": "start",
  "content-type": "audio/l16;rate=44100"
}

websocket.binary(true);
<bytes of binary audio data 50,000 bytes>
<bytes of binary audio data 50,000 bytes>
<bytes of binary audio data 50,000 bytes>
<bytes of binary audio data 50,000 bytes>
<bytes of binary audio data 31,296 bytes>

websocket.binary(false);
{
  "action": "stop"
}

Foo.cpp

 {"results": [
      {"alternatives": [
            {  "confidence": xxxx, 
               "transcript": "call Rohan Chauhan "
            }],"final": true
      }], "result_index": 0
}

这里有任何建议吗?

1 个答案:

答案 0 :(得分:0)

从boost的documentationwebsocket::async_write的以下摘录

  

此函数用于异步写入完整的消息。这个   呼叫总是立即返回。异步操作将   继续,直到满足以下条件之一:

     
      
  1. 将写入完整的消息。

  2.   
  3. 发生错误。

  4.   

例如,当您创建要传递给缓冲区net::buffer(TextStart)的缓冲区对象时,传递给它的buffer的生存期只有在函数返回之前。可能即使在函数返回您之后,根据文档,异步写入仍在缓冲区上进行,但是由于buffer是局部变量,因此内容不再有效。

为解决此问题,可以将TextStart设为静态,或声明您是该类的成员并将其复制到boost::asio::buffer上,这里有许多示例。注意我只在IbmWebsocketSession::send_start函数中提到了TextStart。在整个代码中,问题几乎相同。

在IBM Watson的API definition中,发起连接需要某种格式,然后可以将其表示为字符串。您有字符串,但是缺少正确的格式,导致对等方关闭了连接,并且您正在写入关闭的套接字,从而损坏了管道。

发起连接需要:

  var message = {
    action: 'start',
    content-type: 'audio/l16;rate=22050'
  };

可以根据您的要求将其表示为string TextStart = "action: 'start',\r\ncontent-type: 'audio\/l16;rate=44100'"

在聊天中的讨论之后,OP通过添加以下代码解决了该问题:

if (!IsLast ) {
    ws_.async_write(net::buffer(binarydata, Datasize),
    bind(&IbmWebsocketSession::send_binary, shared_from_this(),
    placeholders::_1));
} 
else {
     if (mIbmWatsonobj->IsGstFileWriteDone()) { //checks for the file write completion
         IbmWebsocketSession::on_binarysent(ec);
     } else {
         std::this_thread::sleep_for(std::chrono::seconds(1));
         IbmWebsocketSession::send_binary(ec);
     }
}

从讨论中得出的结论是,在对同一字节集完成文件写入之前,有更多的字节被发送到客户端。现在,OP会在尝试发送更多字节之前对其进行验证。