通常webapi实现通过http get/post请求,返回文本型的json,xml等字符串。本文以Tomcat8为web服务器,借助protobuf框架,响应二进制数据。
由于protobuf协议能跨语言,我们可以用java servlet实现服务端,C/C++实现客户端,达到各模块解耦目的。双方需设置ContentType为application/x-protobuf。
1. 准备proto文件
package qwd.kettas; // 请求结构 message CTestReq { optional uint32 ShopId = 1; // 店铺ID } message CProduct { optional uint32 Id = 1; // 商品ID optional bytes Name = 2; // 商品名称 optional double price = 3; // 商品价格 } // 响应结构 message CTestResp { optional int32 Total = 1; // 商品总数 repeated CProduct Product = 2; // 商品数组 }
2. Java Servlet服务
/** * Servlet 服务实现,接收post请求,响应protocol buffer二进制数据 */ protected void service( HttpServletRequest req, HttpServletResponse resp ) throws ServletException, IOException { /* * 注:用in.read() 无数据部分填充0,会导致parseFrom()失败,不可行。 byte[] postBuf = new byte[128]; InputStream in = req.getInputStream(); int len = in.read( postBuf ); */ // protobuf 解析参数 CTestReq tReq = CTestReq.parseFrom( req.getInputStream() ); // InputStream作为参数 int shopid = tReq.getShopId(); // 准备数据 CTestResp.Builder pBuilder = CTestResp.newBuilder(); pBuilder.setTotal(2); // 产品一 CProduct.Builder pProBuild1 = CProduct.newBuilder(); pProBuild1.setId( shopid + 1001 ); pProBuild1.setName( ByteString.copyFrom("小明","UTF-8") ); // 字符串需要通过ByteString转化,最好定义string pProBuild1.setPrice(15.8); pBuilder.addProduct( pProBuild1 ); // 产品二 pProBuild1 = CProduct.newBuilder(); pProBuild1.setId( shopid + 1002 ); pProBuild1.setName( ByteString.copyFrom("小王","UTF-8") ); pProBuild1.setPrice(29.8); pBuilder.addProduct( pProBuild1 ); // reponse CTestResp pResp = pBuilder.build(); System.out.println( "Data: " + pResp.toString() ); // 序列化 byte[] buff = pResp.toByteArray(); // 响应,设置HTTP头部为: application/x-protobuf resp.setContentType("application/x-protobuf"); resp.getOutputStream().write( buff ); // 发送 }
3. 客户端测试
// 数据回调函数 size_t OnWriteData( void* buffer, size_t size, size_t nmemb, void *lpVoid ) { std::string* str = dynamic_cast<std::string*>((std::string *)lpVoid); if ( NULL == str || NULL == buffer ) { return -1; } char* pData = (char*)buffer; str->append(pData, size * nmemb); return nmemb; } // curl模拟post请求 void TestCurl() { printf( "\n****************TestCurl*******************\n" ); const char *url = "http://10.14.230.7:8080/protoweb/proto"; CTestReq req; CTestResp resp; string sReq; string sResp; req.set_shopid( 1500 ); // 序列化请求 if ( !req.SerializeToString(&sReq) ) return; curl_slist *m_header = NULL; m_header = curl_slist_append( m_header, "Content-Type: application/x-protobuf" ); // 设置消息头 CURL *curl = curl_easy_init(); curl_easy_setopt( curl, CURLOPT_HTTPHEADER, m_header ); // Header curl_easy_setopt( curl, CURLOPT_REFERER, "nginx" ); curl_easy_setopt( curl, CURLOPT_VERBOSE, 1L ); curl_easy_setopt( curl, CURLOPT_URL, url ); curl_easy_setopt( curl, CURLOPT_NOSIGNAL, 1); curl_easy_setopt( curl, CURLOPT_POSTFIELDS, sReq.c_str() ); // Post curl_easy_setopt( curl, CURLOPT_POSTFIELDSIZE, sReq.length() ); curl_easy_setopt( curl, CURLOPT_WRITEFUNCTION, OnWriteData ); curl_easy_setopt( curl, CURLOPT_WRITEDATA, (void*)&sResp ); // Accept data CURLcode ret = curl_easy_perform( curl ); assert( ret == CURLE_OK ); curl_easy_cleanup( curl ); curl_slist_free_all( m_header ); // 反序列化数据 if ( !resp.ParseFromString(sResp) ) return; printf( "Response: %s\n", resp.DebugString().c_str() ); }
执行结果,curl发起post请求,返回46字节内容:
相关推荐
基于C++ module库 Protobuf Zookeeper 实现的Rpc框架.zip基于C++ module库 Protobuf Zookeeper 实现的Rpc框架.zip基于C++ module库 Protobuf Zookeeper 实现的Rpc框架.zip基于C++ module库 Protobuf Zookeeper 实现...
Unity3D & Java 基于 Protobuf 通信实现,客户端代码
google的PROTOBUF机制基于C语言的实现,源代码
使用java语言编写的,基于netty和protobuf的聊天系统,有客户端和服务器。
基于C++实现使用protobuf完成网络通信源码.zip基于C++实现使用protobuf完成网络通信源码.zip基于C++实现使用protobuf完成网络通信源码.zip基于C++实现使用protobuf完成网络通信源码.zip基于C++实现使用protobuf完成...
基于C++ module库 Protobuf Zookeeper实现的Rpc框架源码+项目说明.zip 编译: `./autobuild.sh` 运行 bin目录下: `./provider -i test.conf ` (启动Rpc提供者) `./consumer -i test.conf`(启动Rpc调用者) ...
一个基于Nacos、Netty、Protobuf 实现的简单易懂的RCP框架.zip
基于netty与protobuf的Android手机视频实时传输。先启动server端的T6Client,然后启动手机上的apk,点连接,传输,即可将手机摄像头拍摄的视频传输到pc端
rust 基于tokio-websockets actor tls demo chat server(websocket) 聊天服务器,全异步实现,使用protobuf协议,所属分类 后端没有rust 这里只好下载c++
本资源提供了一个基于protobuf反射特性的pb结构与json相互转换的实例,该实例程序主要有两个核心函数myMessage2Json、myJson2Message。前者的作用是将pb结构转换成对应的json,后者是将json转换成对应的pb结构体。...
基于protobuf和gRPC的消息订阅服务器和客户端 Python实现 支持配置最短消息存在时间和最大连接客户端数
基于Netty+TCP+Protobuf实现的Android IM库,包含Protobuf序列化、TCP拆包与粘包、长连接握手认证、心跳机制、断线重连机制、消息重发机制、读写超时机制、离线消息、线程池等功能
对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】: 有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 鼓励下载和使用,并欢迎大家互相学习,共同...
一个基于Java的开源游戏服务器框架实现,使用了Netty、ProtoBuf、Disruptor等
基于protobuf 实现了一套RPC调用,UE4中可以使用,欢迎下载
使用过protobuf的同学肯定对pb的DebugString相关方法再熟悉不过了,其作用就是打印输出pb对象。有些时候我们可能会有根据这个输出还原原始pb对象的需求。仔细观察发现输出并不是标准json格式,也就是说基于json→pb...
即时消息推送服务,基于Netty protobuf-- IM push service based on Netty protocal
对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】: 有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 鼓励下载和使用,并欢迎大家互相学习,共同...
由于项目组现在用的rpc是基于google protobuf rpc协议实现的,所以花了点时间了解下protobuf rpc。rpc对于做分布式系统的人来说肯定不陌生,对于rpc不了解的童鞋可以自行google,这里只是做个简单的介绍。rpc的主要...
cdeer-im, 基于Netty+Redis+protobuf开发的即时通讯服务器