之前接触到需要C++使用WebSocket传输的场景,最终选定了微软的Rest,由于网上资料不是特别多,回调接收遇到了点难点,所以发个帖子给大伙参考一下遇到的坑。
首先创建一个 == Client ==,底下代码二选一:
websocket_client client; //普通的
websocket_callback_client Client; //使用回调的话用这个,基本用这个,本文以这个为主。
接下来设置连接:
#include "头文件,写上自己的.h"
#include <fstream>
#include <iostream>
#include <cpprest/ws_client.h>
#include "cpprest/details/http_helpers.h"
#include <cpprest/producerconsumerstream.h>
#include <string>
#include "json/json.h"
#include <cpprest/http_client.h>
using namespace std;
using namespace web; // Common features like URIs.
using namespace web::http; // Common HTTP functionality
using namespace web::http::client; // HTTP client features
using namespace web::websockets::client;
using namespace concurrency::streams; // Asynchronous streams
web::web_proxy proxy(U("http://xxx.xx.xx.x:8080")); //设置代理
//web::credentials cred(U(""), U(""));
//proxy.set_credentials(cred);
websocket_client_config config;
config.set_proxy(proxy);
//config.set_validate_certificates(false);
websocket_callback_client client(config);
Client = client;
Client.connect(U("这里是要链接的服务器地址")).wait();
向服务器发送Byte,传Byte的话要自己拼接要发送的数据,且要跟服务器协商好发送多少多少位都是啥数据。
这部分是拼接要发送的数据
long length = lBufferSize; //这个是要传输的图像流大小
int CLIENT_KEY_LEN = 30;
int MAX_CLIENT_NAME = 40;
std::string clientName = "This is name";
std::string clientKey = "01234-56789";
std::string sessionId = "自己编一个";
std::byte* bclientName = new std::byte[MAX_CLIENT_NAME_LEN]();
std::memcpy(bclientName, clientName.data(), clientName.size());
std::byte* bclientKey = new std::byte[clientKey.size()]();
std::memcpy(bclientKey, clientKey.data(), clientKey.size());
std::byte* bsessionId = new std::byte[sessionId.size()]();
std::memcpy(bsessionId, sessionId.data(), sessionId.size());
std::byte* payload = new std::byte[MAX_CLIENT_NAME + clientKey.size() + sessionId.size() + length](); // 拼到一起
int offset = 0;
std::memcpy(payload + offset, bclientName, MAX_CLIENT_NAME);
offset += MAX_CLIENT_NAME;
std::memcpy(payload + offset, bclientKey, clientKey.size());
offset += clientKey.size();
std::memcpy(payload + offset, bsessionId, sessionId.size());
offset += sessionId.size();
std::memcpy(payload + offset, pBuffer, length); //在Byte流中末尾加上了图片的Byte,pBuffer就是图像的
offset += length;
接下来是发送部分 重点
websocket_outgoing_message msg;
concurrency::streams::producer_consumer_buffer<uint8_t> buf;
auto send_task = buf.putn_nocopy((uint8_t*)payload, offset).then([&](size_t offset) { //发送byte
msg.set_binary_message(buf.create_istream(), offset);
return Client.send(msg);
}).then([](pplx::task<void> t)
{
try
{
t.get();
}
catch (const websocket_exception& ex)
{
std::cout << ex.what();
}
});
Client.set_message_handler(receive); // 异步 这里是重点,传入的receive是接受信息的方法,代码放下面
处理接受的信息 receive函数,我用的解析Json
void receive(websocket_incoming_message ret_msg) {
Json::Reader jsonReader;
Json::Value jsonValue;
if (jsonReader.parse(ret_str, jsonValue)) {
if ("歌姬" == jsonValue["初音"][0]["未来"].asString()) {
// 巴拉巴拉,这部分是解析了接收的Json,按照自己需求写
}
}
}
- 完
以上是全部代码,
发送的部分如果不是发送二进制的话使用下面代码
websocket_outgoing_message msg;
msg.set_utf8_message("I am a UTF-8 string! (Or close enough...)");
client.send(msg).then([](){ /* Successfully sent the message. */ });
client.receive().then([](websocket_incoming_message msg) {
return msg.extract_string();
}).then([](std::string body) {
std::cout << body << std::endl;
});