[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: hlengithub.com
5.3 ch->pipeline()->add_last( handler )
将handler添加到handler链表末尾
(此篇文章待进一步整理)
完整的工程地址如下:
Netplus 之 PINGPONG工程github.com
知识库:
Netplus之WIKIgithub.com
如果你喜欢我的文章,请加个关注,点个赞,谢谢。
写代码的冰冰
姑苏城里平江路,入夜细雨扰我心,再会。
想把我说给你听,,,
总结
以上是生活随笔为你收集整理的[netplus]初见,Netplus快速开始之PingPong Example的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: java页面标签span_span标签跳
- 下一篇: 语音助手为什么需要搜索?