1. 程式人生 > >happy-ip開發tcp client樣例(protobuf版)

happy-ip開發tcp client樣例(protobuf版)

主函式程式碼如下

#include <ip/client/tcp_client.h> #include "proto_client_message_factory.h" #include <iostream> #include <utils.h> #include <thread> #include <chrono> #include "dmo.pb.h" #include <network/proto_network_convert.h> #ifdef GLOG_OUTPUT #include <config_glog.h> #endif using namespace happy::utils::network; using namespace std; using namespace happy::asio::ip;

int main(int argc, char* argv[]) {     // 預設建立執行緒池的大小為4。     //IoServicePool::singleton::Create(4);  #ifdef GLOG_OUTPUT     happy::utils::ConfigGlog(argv[0]); #endif     auto tcp_client = make_shared <TcpClient>();     tcp_client->SetMessageFactory(dynamic_pointer_cast <happy::asio::ip::MessageFactory>(make_shared <ProtoClientMessageFactory>("", true)));     auto const ip = "127.0.0.1";     auto const port = 1234;     cout << "connect to " << ip << ":" << port << endl;     tcp_client->Connect(ip, port);     cout << "connection is successful" << endl;     thread t([]() { IoServicePool::singleton::GetInstance()->Run(); });     t.detach();     while (true)     {         cout << "please input send server string(enter to end): ";         char buffer[1024];         cin >> buffer;         auto request_info = make_shared <RequestInfo>();         request_info->set_info(buffer);         string out_buffer;         ProtoNetworkConvert::singleton::GetInstance()->ToNetwork(request_info, out_buffer);         tcp_client->AsyncWrite(out_buffer);         this_thread::sleep_for(chrono::seconds(1));         //cin.getline(buffer, size(buffer));     }     return EXIT_SUCCESS; }

        主函式中只需要例項化TcpClient類(TcpClient類建構函式提供引數auto_reconnect,預設為true,自動發起非同步重連),設定TcpClient類的MessageFactory。IoServicePool如果沒有呼叫create函式, 預設建立執行緒池的大小為4。一定記得在最後呼叫IoServicePool類的run函式,啟動io執行緒池。本例使用的是Connect函式(同步連線),也可以使用AsyncConnect發起非同步連線。 ProtoClientMessageFactory類建構函式提供了is_read_print引數,設定為true代表網路層自動列印收到的protobuf訊息。預設列印訊息到終端視窗,如果定義了GLOG_OUTPUT巨集,日誌就會通過glog方式輸出。使用glog方式輸出日誌,需在使用前呼叫ConfigGlog函式。

ProtoClientMessageFactory.h程式碼如下

#pragma once #include <network/client_message_factory.h> #include <utils.h> using namespace happy::utils::network;

class ProtoClientMessageFactory : public ClientMessageFactory { public:     ProtoClientMessageFactory(const string& closed_print = "", const bool is_read_print = false); private:     virtual shared_ptr <Message> Produce(const shared_ptr <News> news) override final;     shared_ptr <Message> ResponseInfoHandler(const shared_ptr<Message> message); };

        繼承於ClientMessageFactory類,不用實現Create虛擬函式。定義處理各種protobuf訊息的函式,此出為ResponseInfoHandler函式,專門處理ResponseInfo訊息。

ProtoClientMessageFactory.cpp程式碼如下

#include "proto_client_message_factory.h" #include "dmo.pb.h"

ProtoClientMessageFactory::ProtoClientMessageFactory(const string& closed_print, const bool is_read_print)     : ClientMessageFactory(closed_print, is_read_print) {     handler_[RequestInfo::descriptor()->full_name()] = std::bind(&ProtoClientMessageFactory::ResponseInfoHandler, this, std::placeholders::_1); }

shared_ptr <Message> ProtoClientMessageFactory::Produce(const shared_ptr <News> news) {     return nullptr; }

shared_ptr <Message> ProtoClientMessageFactory::ResponseInfoHandler(const shared_ptr<Message> message) {     //auto response_info = dynamic_pointer_cast <ResponseInfo>(message);     return nullptr; }

        建構函式中動態繫結protobuf訊息的RPC函式。RPC函式ResponseInfoHandler將收到ResponseInfo訊息,通過動態轉換即可使用。由於ClientMessageFactory類已設定無應答訊息,所以RequestInfoHandler函式必須返回nullptr訊息。

執行結果如下(打開了GLOG_OUTPUT開關)

connect to 127.0.0.1:1234 connection is successful please input send server string(enter to end): 1I0930 20:37:22.878049  4340 util_message_factory.cpp:19] receive message: happy.utils.network.ResponseInfo I0930 20:37:22.878049  4340 util_message_factory.cpp:22] info: "server response data" please input send server string(enter to end): 333I0930 20:37:25.224450  4340 util_message_factory.cpp:19] receive message: happy.utils.network.ResponseInfo I0930 20:37:25.224450  4340 util_message_factory.cpp:22] info: "server response data" please input send server string(enter to end):

        表示連線伺服器成功,收到伺服器2條應答資訊。每條訊息佔2行輸出,第1行表示收到服務端的protobuf訊息全稱,第2行表示訊息的具體內容。是不是很簡單,歡迎大家使用。

資源下載

windows編譯引數

cmake .. -LA -DBOOST_INCLUDE_DIR='E:\git\3rdparty\include' -DBOOST_LIB_DIR='E:\git\3rdparty\lib\win32_debug' -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS_DEBUG="/MTd /Zi /Ob0 /Od /RTC1" -DBUILD_EXAMPLES=ON -DBUILD_NETWORK=ON -DGLOG_OUTPUT=ON

linux編譯引數

cmake .. -LA -DBOOST_INCLUDE_DIR='/mnt/e/git/3rdparty/include' -DBOOST_LIB_DIR='/mnt/e/git/3rdparty/lib/linux_debug' -DCMAKE_BUILD_TYPE=Debug -DBUILD_EXAMPLES=ON -DBUILD_EXAMPLES=ON -DBUILD_NETWORK=ON -DGLOG_OUTPUT=ON