微软开发了一个开源跨平台的http库--C++ REST SDK(http://casablanca.codeplex.com/),又名卡萨布兰卡Casablanca,有个电影也叫这个名字,也许这个库的作者很喜欢这个电影吧。从REST SDK这个名字可以看出它是处理rest API的,对REST不了解的童鞋可以点这里这里,由于REST API的请求支持application/x-www-form-urlencoded、application/json、application/octet-stream等多种编码方式,REST API的返回值都是json形式,很方便返回对象。Casablanca采用c++11开发,集成了PPL和asio,支持异步数据流和web socket,用起来很方便。下面来看看官方的一个例子吧:

#include <cpprest\http_client.h>
#include <cpprest\filestream.h>
using namespace utility;
using namespace web;
using namespace web::http;
using namespace web::http::client;
using namespace concurrency; void TestRequest()
{
auto fileStream = std::make_shared<concurrency::streams::ostream>();
pplx::task<void> requestTask = concurrency::streams::fstream::open_ostream(U("result.html")).then([=](concurrency::streams::ostream outFile){
*fileStream = outFile; http_client client(U("http://www.bing.com/"));
uri_builder builder(U("/search"));
builder.append_query(U("q"), U("Casablanca CodePlex")); return client.request(methods::GET, builder.to_string());
})
.then([=](http_response response)
{
return response.body().read_to_end(fileStream->streambuf());
}).then([=](size_t len){
return fileStream->close();
}); try
{
requestTask.wait();
}
catch (const std::exception& e)
{
cout << e.what() << endl;
}
}

  这个例子把从bing.com上查询“Casablanca CodePlex”的内容保存到一个本地文件result.html中,用到了ppl的串行任务。启用了四个异步任务,第一个任务是打开一个文件流,接着,发起了第二个任务,用于发起一个查询请求,然后,第三个任务等待请求的响应,并将响应的结果输入到文件中去,第四个任务是关闭文件流。要注意rest sdk的字符相关的入参是宽字符(wchr_t)。这种处理http的方式让我们处理http的流程变得很清晰,有点小清新^_^,不过,这对于不太熟悉ppl用法的童鞋可能有点难接受,没关系,让我来简化一下,简化成同步方式,看得就更清楚了。

void TestRequest()
{
auto fileStream = std::make_shared<concurrency::streams::ostream>();
concurrency::streams::ostream outFile = concurrency::streams::fstream::open_ostream(U("result11.html")).get();
*fileStream = outFile; http_client client(L"http://www.bing.com/");
uri_builder builder(L"/search");
builder.append_query(L"q", L"Casablanca CodePlex"); http_response response = client.request(methods::GET, builder.to_string()).get();
response.body().read_to_end(fileStream->streambuf()).get();
fileStream->close().get();
}

  注意上面的get()方法会阻塞等待异步线程完成操作。这样简化之后就能更清晰的看到如何使用rest sdk了,下面来说说发起http操作的几个对象。 http_client代表客户端,需要它发起http请求。rest api一般是基于一个基本URL增加了一些URL,比如上例中的search,还有可能有一些url参数,这时,我们就需要uri_builder来做这些拼接url和参数的事情,用起来很简单。

uri_builder builder;
builder.append_path(L"search"); //添加URL
builder.append_query(L"q", L"Casablanca CodePlex"); //添加url参数

  待url和参数准备好之后就可以发起请求了,请求方式可以用methods::GET和methods::POST等方式。

client.request(methods::GET, builder.to_string()).get();

  上面的例子中并没有request body,有时候我们发起http请求还需要request body,一般是json或者二进制格式,来看一个post json格式的request body的例子,rest sdk提供了json对象来解析json,用起来也很方便:

uri_builder builder;
builder.append_path(L"/test"); json::value obj;
obj[L"Count"] = json::value::number();
obj[L"Version"] = json::value::string(L"1.0");
client.request(methods::POST, builder.to_string(), obj.serialize(), L"application/json");

  如果request body为二进制格式的话,这样发请求就可以了:

wchar_t buf[] = {};
http_response response = client.request(methods::POST, builder.to_string(), buf/*L""*/, L"application/octet-stream").get();

  请求发起之后就等http响应了,rest api返回的结果都是json格式的,所以我们需要解析json对象,rest sdk提供了http_response对象来处理响应。假设http响应的结果是这样的:

{
"result":"service failed"
"error_code":
}

  http响应的处理:

if (response.status_code() == status_codes::OK)
{
try
{
result = true;
const json::value& jv = response.extract_json().get();
const web::json::object& jobj = jv.as_object();
auto result = jobj.at(L"result").as_string();
auto access_code = result.as_object().at(L"error_code").as_string();
wcout << result<<" "<< access_code << endl;
}
catch (const std::exception& e)
{
cout << e.what() << endl;
}
}

  用wcout输出宽字符时需要做一个初始化,否则可能输出不了内容。

wcout.imbue(locale("chs"));//本地化

  我们还可以设置相关的http属性,http_client默认的超时时间是30秒,我们也可以自己设置超时时间:

http_client_config config;
config.set_timeout(utility::seconds()); //设置为90秒超时
http_client client(URL, config);

总结:可以看到C++ REST SDK的用法是很简单的,uri的解析和拼接,json的处理,请求和响应的处理都有相应的对象,我们用起来就很省心了。微软提供的C++ REST SDK真是个好东西,值得我们深入去研究。

C++ REST SDK的基本用法的更多相关文章

  1. Opentelemetry SDK的简单用法

    Opentelemetry SDK的简单用法 概述 Opentelemetry trace的简单架构图如下,客户端和服务端都需要启动一个traceProvider,主要用于将trace数据传输到reg ...

  2. Intel Media SDK H264 encoder GOP setting

    1 I帧,P帧,B帧,IDR帧,NAL单元 I frame:帧内编码帧,又称intra picture,I 帧通常是每个 GOP(MPEG 所使用的一种视频压缩技术)的第一个帧,经过适度地压缩,做为随 ...

  3. Android中直播视频技术探究之---采集摄像头Camera视频源数据进行推流(采用金山云SDK)

    一.前言 在之前已经详细介绍了Android中的一种视频数据源:Camera,不了解的同学可以点击进入:Android中Camera使用详解 ,在这篇文章中我们介绍了如何采集摄像头的每一帧数据,然后进 ...

  4. Android消息推送 SDK 集成指南

    使用提示 本文是 Android SDK 标准的集成指南文档. 匹配的 SDK 版本为:r1.8.0及以后版本. 本文随SDK压缩包分发.在你看到本文时,可能当前的版本与本文已经不是很适配.所以建议关 ...

  5. 创建完美SDK的10个技巧

    [编者按]本文作者为 Gal Lavinsky,文中将列出10个零基础小技巧,帮你创建完美的Java SDK.文章系国内 ITOM 管理平台 OneAPM 编译呈现.以下为正文. 本文起源于笔者朋友的 ...

  6. vmware之VMware Remote Console (VMRC) SDK(三)

    前两节我们介绍了vmrc sdk的基本用法.在前面的demo中,有一个关键的问题是,我们现在所作的工作都是基于局域网的,作为应用层面上,主机不会直接暴露给用户,而是通过一系列的web service服 ...

  7. Android消息推送——JPush极光推送

    刚看了一篇关于Android消息推送评测总结的博客http://www.cnblogs.com/logan/p/4514635.html: 自己也对原学过的JPush极光进行一下小结,方便后续工作使用 ...

  8. iOS - 语音云通讯

    iOS SDK 2.0 语音及图片消息详解本文档将详细介绍融云的语音及图片消息接口功能及使用说明.阅读本文前,我们假设您已经阅读了融云 iOS 开发指南,并掌握融云 SDK 的基本用法. 语音消息用来 ...

  9. Java编程的逻辑 (86) - 动态代理

    ​本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http: ...

随机推荐

  1. Ant: Class not found: javac1.8

    今天用ant,在选择build.xml,run as ant build后出错Ant: Class not found: javac1.8 分析问题:是否是eclipse中的ant版本和java的版本 ...

  2. 开始研究tigase和android客户端的实现

    2015.7.5. 昨晚总算把tigaase7.0的开发环境搭起来了.稍微看了下代码结构. 主要是auth,db,compnent,cluster,server,xmpp,这几块,准备先发点时间看看开 ...

  3. Jackson fasterxml跟codehaus的区别 (fasterxml vs. codehaus) -- 转载

    Jackson fasterxml和codehaus的区别: 他们是Jackson的两大分支.也是两个版本的不同包名.Jackson从2.0开始改用新的包名fasterxml:1.x版本的包名是cod ...

  4. 通过viewmodel找到view

    如何通过viewmodel找到view? 之前的做法是,在view加载时(Loaded),将view保存到viewmodel中,后来想想Caliburn-Micro,自带方法可以通过viewmodel ...

  5. js二维数组与字符串

    1. 二维数组:数组中的元素,又引用了另一个数组对象 何时使用:只要保存横行竖列的数据, 具有上下级包含关系的数据, 创建二维数组: 1. var arr=[]; col arr[0]=[" ...

  6. MvcPager 免费开源分页控件3.0版发布!

    MvcPager 3.0版在原2.0版的基础上进行了较大的升级,对MvcPager脚本插件重写并进行了大量优化.修复了部分bug并新增了客户端Javascript API等功能,使用更方便,功能更强大 ...

  7. JS、C#及SQL中的DateTime

    一:SQL中的DataTime 1.       between and 相当于>= and <= 2.       常用的将DataTime查询成字符串的方法 Select CONVER ...

  8. 通俗易懂的 JSon解析处理

    1.主要用到的类: 主要用到了JavaScriptSerializer类,该类在System.Web.Script.Serialization命名空间(在System.Web.Extensions.d ...

  9. vi/vim使用进阶: vimrc初步

    本节所用命令的帮助入口: :help compatible :help mapleader :help map :help autocmd 当vim在启动时,如果没有找到vimrc或gvimrc,它缺 ...

  10. Swift - mutating关键字的使用

    转载自:http://www.jianshu.com/p/14cc9d30770a  感谢作者:此ID想了很久 Swift中protocol的功能比OC中强大很多,不仅能再class中实现,同时也适用 ...