[netplus]初见,Netplus快速开始之PingPong Example
繼上篇?初心之讓人人能寫高性能服務(wù)器?已一星期,我們?nèi)陨形粗\面,我已迫不及待,是否還記得我曾經(jīng)對(duì)你的承諾,我說,要讓人人能編寫高性能網(wǎng)絡(luò)服務(wù)器,當(dāng)然,這只是我一相情愿的告白,我不知道有沒有被你看上,也不知道你是否還愿意在這條道上與我走一走,我們一起談一談,未來…
看起來這是一個(gè)夢(mèng)啊,夢(mèng)是當(dāng)不得真的,但夢(mèng)想還是可以做做的。
在這所有的所有的一切開始之前,我們還是不落俗套地見上一見吧,你說,自古套路得人心,而大家又總傾心于Hello World,要不,我們換一個(gè),Ping Pong可好。
請(qǐng)你忘記你關(guān)于網(wǎng)絡(luò)編程的想象,保留那么一點(diǎn)點(diǎn)CPP的印象,因?yàn)?#xff0c;好的忘記,是新的開始,而CPP正是我們的主角。
要懂東西的不多,我們就從最基本的問題開始吧。
[備注:此篇為初稿,期待你的反饋]
在開始之前,建議先閱讀以下前置知識(shí):
PINGPONG Example
本篇,我們將演示如何實(shí)現(xiàn)一個(gè)完整版的PingPong服務(wù)器,以及客戶端。
讀完本文,你應(yīng)該能用Netplus進(jìn)行簡(jiǎn)單消息收發(fā)。
1. PINGPONG服務(wù)器
代碼如下:
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的總體執(zhí)行邏輯
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應(yīng)用,netp::app app總是第一行代碼,app實(shí)例代表著一個(gè)netplus對(duì)象,用處初始化netplus系統(tǒng),設(shè)置信號(hào)處理。
app.run() 等待退出信號(hào)
5.2 Channel Handler hlen
- 這個(gè)handler用于處理格式為長(zhǎng)度+內(nèi)容的消息,內(nèi)容長(zhǎng)度占4bytes
- 發(fā)送時(shí)為消息添加消息長(zhǎng)度,占4byte
- 接收時(shí),先讀4byte作為長(zhǎng)度,然后按讀到的長(zhǎng)度繼續(xù)讀bytes, 直到讀完給定的長(zhǎng)度后,將read事件傳遞給下一個(gè)Handler,詳細(xì)的描述,請(qǐng)參閱:
Netplus 之 Handler: hlen?github.com
?
5.3 ch->pipeline()->add_last( handler )
將handler添加到handler鏈表末尾
(此篇文章待進(jìn)一步整理)
完整的工程地址如下:
Netplus 之 PINGPONG工程?github.com
?
知識(shí)庫:
Netplus之WIKI?github.com
?
?
如果你喜歡我的文章,請(qǐng)加個(gè)關(guān)注,點(diǎn)個(gè)贊,謝謝。
?
寫代碼的冰冰
姑蘇城里平江路,入夜細(xì)雨擾我心,再會(huì)。
?
想把我說給你聽,,,
總結(jié)
以上是生活随笔為你收集整理的[netplus]初见,Netplus快速开始之PingPong Example的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java页面标签span_span标签跳
- 下一篇: 语音助手为什么需要搜索?