websocket_client_main.cc

websocket_client_main.cc

可执行文件路径:wenet/runtime/libtorch/build/bin/websocket_client_main

直接执行

与前一篇《websocket_server_main.cc》相同。

调试

1
2
3
4
5
6
7
8
9
10
# cd runtime/libtorch
export GLOG_logtostderr=1
export GLOG_v=2
# 在一个命令行窗口,执行
bash websocket_server.sh

# 在另一个命令行窗口,执行
cgdb ./build/bin/websocket_client_main
# 打断点 比如 b core/websocket/websocket_client.cc:55
run --hostname 127.0.0.1 --port 10086 --wav_path test.wav

过程解释

client建立与server的连接(发起请求):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// core/websocket/websocket_client.cc:

void WebSocketClient::Connect() {
tcp::resolver resolver{ioc_};
// Look up the domain name
auto const results = resolver.resolve(hostname_, std::to_string(port_));
// Make the connection on the IP address we get from a lookup
auto ep = asio::connect(ws_.next_layer(), results);
// Provide the value of the Host HTTP header during the WebSocket handshake.
// See https://tools.ietf.org/html/rfc7230#section-5.4
std::string host = hostname_ + ":" + std::to_string(ep.port()); // 比如 127.0.0.1:10086
// Perform the websocket handshake
ws_.handshake(host, "/");
}

然后新建子线程,子线程里执行 ReadLoopFunc() 函数,主线程发送开始符给server,是一个text格式的字符串,write写进ws_里,也就是和server发消息(发开始符)(对应函数为 SendTextData(const std::string& data) , data内容是{\"signal\":\"start\",\"nbest\":1,\"continuous_decoding\":false})。主线程接着往下走,读取要识别的音频,然后每隔0.5s发送0.5s的音频数据给server,发送给server了就休息一下,sleep 0.5s,直到把音频数据全发送完,再发送结束符。然后等待子线程里 ReadLoopFunc()函数执行完,主线程也结束。

ReadLoopFunc() 函数作用:这个函数作用是验证server返回的消息是不是正常的。

ReadLoopFunc()函数流程:(主线程client已经给server发送开始请求了),用 while(true)循环一直在read读取 server返回的消息,确认client接收到消息的status一直是ok的,如果不ok,就会break退出循环。而server端发送不ok的情况就是进入OnError()函数,里面的status会是failed,会发给client非ok的状态,而此时server的代码会执行ws_.close(),也就是断开和client的连接,因此起到验证server返回的消息是否正常的功能。

然后一直到client接收到消息的type是speech_end字符串,也会break退出循环,结束子线程。