通常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 实现...
2. **nanopb简介**:`nanopb`由Jesse Tuomela开发,主要针对嵌入式系统,提供了一个轻量级的protobuf实现。它不依赖动态内存分配,且支持代码生成,使得开发者能够轻松地将protobuf消息集成到C代码中。 3. **移植...
本教程将深入探讨如何利用Protocol Buffers(Protobuf)在Unity3D客户端与Java服务器之间实现通信。Protocol Buffers是一种高效的数据序列化协议,由Google开发,它能够将结构化数据转化为二进制格式,便于网络传输...
这个项目“基于netty和protobuf的聊天系统,客户端+服务器”就是这样一个实例,它展示了如何利用Java语言结合Netty框架和Protocol Buffers(protobuf)来搭建一个高性能、低延迟的聊天应用。 Netty是一个开源的异步...
Netty、HTTP与Protobuf是三个在IT领域中至关重要的技术组件,它们分别在不同的层面上为高...通过Netty实现HTTP服务器和客户端,利用Protobuf进行高效的数据序列化和反序列化,可以极大地提升应用程序的性能和可扩展性。
总之,这个“protobuf实例-C#-聊天服务器”项目提供了一个使用protobuf进行网络通信的示例,展示了如何在C#中利用protobuf实现高效的序列化和反序列化,以及如何构建简单的聊天服务器。通过对该项目的研究和学习,...
rust 基于tokio-websockets actor tls demo chat server(websocket) 聊天服务器,全异步实现,使用protobuf协议,所属分类 后端没有rust 这里只好下载c++
基于C++实现使用protobuf完成网络通信源码.zip基于C++实现使用protobuf完成网络通信源码.zip基于C++实现使用protobuf完成网络通信源码.zip基于C++实现使用protobuf完成网络通信源码.zip基于C++实现使用protobuf完成...
开发者可以克隆或下载这个仓库,然后在本地环境中编译和运行项目,以了解和学习如何利用Nacos、Netty和Protobuf实现RPC框架。 这个框架的实现对于学习分布式系统、网络编程以及序列化技术非常有帮助。开发者可以...
总之,基于protobuf的socket通信在Android中能够提供高效、简洁的数据交换方式。通过protobuf定义数据结构,使用socket进行网络通信,可以构建稳定可靠的Android应用与服务器之间的通信桥梁。在实际项目中,你可以...
本项目“基于Netty与Protobuf的Android手机视频实时传输”利用了高性能的网络库Netty和高效的序列化框架Protobuf,实现了高效、低延迟的视频流传输。下面将详细介绍这两个关键技术及其在该项目中的应用。 **Netty**...
通过反射机制,可以基于Descriptor在运行时处理protobuf消息,实现protobuf与JSON的动态转换。 7. **protobuf的兼容性**:protobuf支持版本兼容性,这意味着新版本的protobuf编译器可以解析旧版本的.proto文件,这...
基于C++ module库 Protobuf Zookeeper实现的Rpc框架源码+项目说明.zip 编译: `./autobuild.sh` 运行 bin目录下: `./provider -i test.conf ` (启动Rpc提供者) `./consumer -i test.conf`(启动Rpc调用者) ...
在本项目"基于protobuf和gRPC的消息订阅服务器和客户端"中,我们将探讨如何使用Python来实现一个这样的系统,它允许客户端订阅并接收来自服务器的消息。 protobuf(Protocol Buffers)是一种数据序列化协议,它可以...
在服务端,我们需要实现一个 Netty 服务器,它接收客户端的请求,解码 protobuf 消息,处理业务逻辑,然后编码回消息给客户端。Netty 中的 `ChannelHandlerContext` 和 `ByteToMessageDecoder`、`...
基于C++,Protobuf实现,以Zookeeper为服务配置中心的分布式RPC通信框架 C++是一种广泛使用的编程语言,它是由Bjarne Stroustrup于1979年在新泽西州美利山贝尔实验室开始设计开发的。C++是C语言的扩展,旨在...
总结起来,这个压缩包提供了一个基于protobuf-net的C#实现,用于数据序列化和反序列化。它对C#开发者尤其有用,同时涉及到C++的背景知识,适合学习者在毕业设计或课程设计中使用,提升跨语言通信和数据交换的技能。...
对于C#开发者,他们可以使用`Google.Protobuf.dll`库来实现数据序列化和反序列化;而对于Python开发者,他们将依赖于对应的Python包,如`protobuf`,来实现相同的功能。 使用Protobuf的优势在于其高效性和跨平台性...