简单的websocket_client.cc

简单的websocket_client.cc

参考的wenet/runtime/里websocker_client_main的写法,里面用了boost库进行websocket。进行语音识别,我这里把代码抠出来,只要websocket通信功能,后续开发什么功能(比如例子的语音识别)都可以。

参考前一篇《简单的websocket_server.cc》

yl_websocket_client.cc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include "yl_websocket_client.h"
#include "boost/json/src.hpp"

namespace beast = boost::beast; // from <boost/beast.hpp>
namespace http = beast::http; // from <boost/beast/http.hpp>
namespace websocket = beast::websocket; // from <boost/beast/websocket.hpp>
namespace asio = boost::asio; // from <boost/asio.hpp>
using tcp = boost::asio::ip::tcp; // from <boost/asio/ip/tcp.hpp>
namespace json = boost::json;

WebSocketClient::WebSocketClient(const std::string& hostname, int port)
: hostname_(hostname), port_(port) {
Connect();
// t_.reset(new std::thread(&WebSocketClient::ReadLoopFunc, this));
}

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);
std::string host = hostname_ + ":" + std::to_string(ep.port());
// Perform the websocket handshake
ws_.handshake(host, "/");
}

void WebSocketClient::SendStartSignal() {
// json::value start_tag = {{"signal", "start"}};
// std::string start_message = json::serialize(start_tag);
std::string start_message = "start";
this->SendTextData(start_message);
}

void WebSocketClient::SendTextData(const std::string& data) {
ws_.text(true);
ws_.write(asio::buffer(data));
}

void WebSocketClient::ReadSignal() {
try {
while (true) {
beast::flat_buffer buffer;
ws_.read(buffer);
if(ws_.got_text()){
std::string message = beast::buffers_to_string(buffer.data());
std::cout << message;
break;
}
}
} catch (beast::system_error const& se) {
// This indicates that the session was closed
if (se.code() != websocket::error::closed) {
std::cout << se.code().message();
}
} catch (std::exception const& e) {
std::cout << e.what();
}
}

int main() {
WebSocketClient client("127.0.0.1", 10021);
client.SendStartSignal();
client.ReadSignal();

return 0;
}

yl_websocket_client.h:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#ifndef WEBSOCKET_WEBSOCKET_CLIENT_H_
#define WEBSOCKET_WEBSOCKET_CLIENT_H_

#include <iostream>
#include <memory>
#include <string>
#include <thread>

#include "boost/asio/connect.hpp"
#include "boost/asio/ip/tcp.hpp"
#include "boost/beast/core.hpp"
#include "boost/beast/websocket.hpp"

namespace beast = boost::beast; // from <boost/beast.hpp>
namespace http = beast::http; // from <boost/beast/http.hpp>
namespace websocket = beast::websocket; // from <boost/beast/websocket.hpp>
namespace asio = boost::asio; // from <boost/asio.hpp>
using tcp = boost::asio::ip::tcp; // from <boost/asio/ip/tcp.hpp>

class WebSocketClient {
public:
WebSocketClient(const std::string& host, int port);

void SendTextData(const std::string& data);
// void SendBinaryData(const void* data, size_t size);
// void ReadLoopFunc();
// void Close();
// void Join();
void SendStartSignal();
void ReadSignal();
// void SendEndSignal();
// bool done() const { return done_; }

private:
void Connect();
std::string hostname_;
int port_;
bool done_ = false;
asio::io_context ioc_;
websocket::stream<tcp::socket> ws_{ioc_};
std::unique_ptr<std::thread> t_{nullptr};
};

#endif // WEBSOCKET_WEBSOCKET_CLIENT_H_

然后在命令行窗口执行 ./build/yl_websocket_server_main 启动server端

在另一个命令行窗口执行 ./build/yl_websocket_client_main

这里的功能是发送了一个start的消息给server,server接收到打印出来,server也发送一条success的消息给client,client接收到打印出来。

server是用多线程,client没有用,这是考虑到多个client向同一个server发起请求的情况。