[netplus]初见,Netplus快速开始之PingPong Example
繼上篇?初心之讓人人能寫高性能服務器?已一星期,我們仍尚未謀面,我已迫不及待,是否還記得我曾經對你的承諾,我說,要讓人人能編寫高性能網絡服務器,當然,這只是我一相情愿的告白,我不知道有沒有被你看上,也不知道你是否還愿意在這條道上與我走一走,我們一起談一談,未來…
看起來這是一個夢啊,夢是當不得真的,但夢想還是可以做做的。
在這所有的所有的一切開始之前,我們還是不落俗套地見上一見吧,你說,自古套路得人心,而大家又總傾心于Hello World,要不,我們換一個,Ping Pong可好。
請你忘記你關于網絡編程的想象,保留那么一點點CPP的印象,因為,好的忘記,是新的開始,而CPP正是我們的主角。
要懂東西的不多,我們就從最基本的問題開始吧。
[備注:此篇為初稿,期待你的反饋]
在開始之前,建議先閱讀以下前置知識:
PINGPONG Example
本篇,我們將演示如何實現一個完整版的PingPong服務器,以及客戶端。
讀完本文,你應該能用Netplus進行簡單消息收發。
1. PINGPONG服務器
代碼如下:
class Pong :public netp::channel_handler_abstract { public:Pong() : channel_handler_abstract(netp::CH_INBOUND_READ){}//for inboundvoid read(netp::ref_ptr<netp::channel_handler_context> const& ctx, netp::ref_ptr<netp::packet> const& income) {//reply with PONGconst std::string pong = "PONG";netp::ref_ptr<netp::packet> PONG = netp::make_ref<netp::packet>(pong.c_str(), pong.length());netp::ref_ptr<netp::promise<int>> write_promise = ctx->write(PONG);//check the reply status once the write operation is donewrite_promise->if_done([](int reply_rt) {NETP_INFO("[PONG]reply PONG, rt: %d", reply_rt );});} };2. PINGPONG客戶端
代碼如下:
class Ping : public netp::channel_handler_abstract { public:Ping():channel_handler_abstract(netp::CH_ACTIVITY_CONNECTED|netp::CH_INBOUND_READ){}void connected(netp::ref_ptr<netp::channel_handler_context> const& ctx) {NETP_INFO("[PING]connected");//initial PINGdo_ping(ctx);}void read(netp::ref_ptr<netp::channel_handler_context> const& ctx, netp::ref_ptr<netp::packet> const& income) {NETP_INFO("[PING]reply income");do_ping(ctx);}void do_ping(netp::ref_ptr<netp::channel_handler_context> const& ctx) {const std::string ping = "PING";netp::ref_ptr<netp::packet> message_ping = netp::make_ref<netp::packet>();message_ping->write(ping.c_str(), ping.length());netp::ref_ptr<netp::promise<int>> write_p = ctx->write(message_ping);write_p->if_done([]( int rt ) {NETP_INFO("[PING]write PING, rt: %d", rt );});} };?
3. PING PONG的總體執行邏輯
4. main 代碼如下:
int main(int argc, char** argv) {//initialize a netplus app instancenetp::app app;std::string host = "tcp://127.0.0.1:13103";netp::ref_ptr<netp::channel_listen_promise> listenp = netp::socket::listen_on(host, [](netp::ref_ptr<netp::channel>const& ch) {ch->pipeline()->add_last( netp::make_ref<netp::handler::hlen>());ch->pipeline()->add_last( netp::make_ref<Pong>() );});int listenrt = std::get<0>(listenp->get());if (listenrt != netp::OK) {NETP_INFO("listen on host: %s failed, fail code: %d", host.c_str(), listenrt);return listenrt;}netp::ref_ptr<netp::channel_dial_promise> dialp = netp::socket::dial(host, [](netp::ref_ptr<netp::channel> const& ch ) {ch->pipeline()->add_last( netp::make_ref<netp::handler::hlen>() );ch->pipeline()->add_last( netp::make_ref<Ping>() );});int dialrt = std::get<0>(dialp->get());if (dialrt != netp::OK) {//close listen channel and returnstd::get<1>(listenp->get())->ch_close();return dialrt;}//wait for signal to exit//Ctrl+C on windows//kill -15 on linuxapp.run();//close listen channelstd::get<1>(listenp->get())->ch_close();//close dial channelstd::get<1>(dialp->get())->ch_close();return 0; }?
5. 代碼解讀
5.1 netp::app
所有的netplus應用,netp::app app總是第一行代碼,app實例代表著一個netplus對象,用處初始化netplus系統,設置信號處理。
app.run() 等待退出信號
5.2 Channel Handler hlen
- 這個handler用于處理格式為長度+內容的消息,內容長度占4bytes
- 發送時為消息添加消息長度,占4byte
- 接收時,先讀4byte作為長度,然后按讀到的長度繼續讀bytes, 直到讀完給定的長度后,將read事件傳遞給下一個Handler,詳細的描述,請參閱:
Netplus 之 Handler: hlen?github.com
?
5.3 ch->pipeline()->add_last( handler )
將handler添加到handler鏈表末尾
(此篇文章待進一步整理)
完整的工程地址如下:
Netplus 之 PINGPONG工程?github.com
?
知識庫:
Netplus之WIKI?github.com
?
?
如果你喜歡我的文章,請加個關注,點個贊,謝謝。
?
寫代碼的冰冰
姑蘇城里平江路,入夜細雨擾我心,再會。
?
想把我說給你聽,,,
總結
以上是生活随笔為你收集整理的[netplus]初见,Netplus快速开始之PingPong Example的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java页面标签span_span标签跳
- 下一篇: 语音助手为什么需要搜索?