基于moduo库实现protobuf通信
基于moduo库实现protobuf通信
服务端:
#include "muduo/proto/codec.h"
#include "muduo/proto/dispatcher.h"#include "request.pb.h"#include "muduo/base/Logging.h"
#include "muduo/base/Mutex.h"
#include "muduo/net/EventLoop.h"
#include "muduo/net/TcpServer.h"#include <iostream>
#include <unordered_map>class Server
{public:typedef std::shared_ptr<google::protobuf::Message> MessagePtr;typedef std::shared_ptr<xyp::TranslateRequest> TranslateRequestPtr;typedef std::shared_ptr<xyp::AddRequest> AddRequestPtr;Server(int port):_server(&_baseloop,muduo::net::InetAddress("0.0.0.0",port),"Server",muduo::net::TcpServer::kReusePort),_dispatcher(std::bind(&Server::onUnknownMessage,this,std::placeholders::_1,std::placeholders::_2,std::placeholders::_3)),_codec(std::bind(&ProtobufDispatcher::onProtobufMessage, &_dispatcher, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)){//注册业务请求函数_dispatcher.registerMessageCallback<xyp::TranslateRequest>(std::bind(&Server::onTranslate,this,std::placeholders::_1,std::placeholders::_2,std::placeholders::_3));_dispatcher.registerMessageCallback<xyp::AddRequest>(std::bind(&Server::onAdd,this,std::placeholders::_1,std::placeholders::_2,std::placeholders::_3));_server.setMessageCallback(std::bind(&ProtobufCodec::onMessage, &_codec, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));_server.setConnectionCallback(std::bind(&Server::onConnection,this,std::placeholders::_1));}void start(){_server.start();_baseloop.loop();}private:std::string translate(const std::string &str){static std::unordered_map<std::string,std::string> dict_map={{"hello","你好"},{"你好", "Hello"},{"thank you","谢谢"}};auto it=dict_map.find(str);if(it==dict_map.end()){return "没听懂!";}return it->second;}void onTranslate(const muduo::net::TcpConnectionPtr& conn, const TranslateRequestPtr& message,muduo::Timestamp){//1.提取message中有效信息std::string req_msg=message->msg();//2。进行翻译得到结果std::string rsp_msg=translate(req_msg);//3.组织protobuf响应xyp::TranslateResponse resp;resp.set_msg(rsp_msg);//4.发送响应_codec.send(conn,resp);}void onAdd(const muduo::net::TcpConnectionPtr& conn, const AddRequestPtr& message,muduo::Timestamp){int num1=message->num1();int num2=message->num2();int result=num1+num2;xyp::AddResponse resp;resp.set_result(result);_codec.send(conn,resp);}void onUnknownMessage(const muduo::net::TcpConnectionPtr& conn, const MessagePtr& message,muduo::Timestamp){LOG_INFO << "onUnknownMessage: " << message->GetTypeName();conn->shutdown();} void onConnection(const muduo::net::TcpConnectionPtr&conn){if(conn->connected()){LOG_INFO<<"新连接成功!";}else{LOG_INFO<<"新连接关闭";}}private:muduo::net::EventLoop _baseloop;muduo::net::TcpServer _server;//服务器对象ProtobufDispatcher _dispatcher;//请求分发器对象,要想其中注册请求函数ProtobufCodec _codec;//protobuf协议处理器,针对收到请求的数据进行protobuf协议处理
};int main()
{Server server(8085);server.start();return 0;
}
客户端:
#include "include/muduo/net/TcpClient.h"
#include "include/muduo/net/EventLoopThread.h"
#include "include/muduo/net/TcpConnection.h"
#include "include/muduo/base/CountDownLatch.h"
#include <iostream>
#include <functional>class TranslateClient
{public:TranslateClient(const std::string&sip,int sport):_latch(1),_client(_loopthread.startLoop(),muduo::net::InetAddress(sip,sport),"Translate"){_client.setConnectionCallback(std::bind(&TranslateClient::onConnection,this,std::placeholders::_1));_client.setMessageCallback(std::bind(&TranslateClient::onMessage,this,std::placeholders::_1,std::placeholders::_2,std::placeholders::_3));}//连接服务器,需要进行阻塞等待连接建立成功之后再进行返回void connect(){_client.connect();//阻塞等待_latch.wait();}bool send(const std::string&msg){if(_conn->connected()){_conn->send(msg);return true;}return false;}private: //连接建立成功时候的回调函数,建立成功的时候,唤醒上面的阻塞void onConnection(const muduo::net::TcpConnectionPtr&conn){if(conn->connected()){_latch.countDown();_conn=conn;}else{//连接操作关闭_conn.reset();}}//收到消息时候的回调函数void onMessage(const muduo::net::TcpConnectionPtr& conn, muduo::net::Buffer* buf, muduo::Timestamp){std::cout<<"翻译结果为:"<<buf->retrieveAllAsString()<<std::endl;}private:muduo::CountDownLatch _latch;muduo::net::EventLoopThread _loopthread;muduo::net::TcpClient _client;muduo::net::TcpConnectionPtr _conn;
};int main()
{TranslateClient client("127.0.0.1",8085);client.connect();while(1){std::string buf;std::cin>>buf;client.send(buf);}return 0;
}
编译文件如下:
all:client server
client:protobuf_client.cpp request.pb.cc ../include/muduo/proto/codec.ccg++ -std=c++11 $^ -o $@ -I../include -L../lib -lmuduo_net -lmuduo_base -pthread -lprotobuf -lz
server:protobuf_server.cpp request.pb.cc ../include/muduo/proto/codec.ccg++ -std=c++11 $^ -o $@ -I../include -L../lib -lmuduo_net -lmuduo_base -pthread -lprotobuf -lz