重寫(xiě)Sylar基于協(xié)程的服務(wù)器(7、TcpServer & HttpServer的設(shè)計(jì)與實(shí)現(xiàn))
重寫(xiě)Sylar基于協(xié)程的服務(wù)器系列:
重寫(xiě)Sylar基于協(xié)程的服務(wù)器(0、搭建開(kāi)發(fā)環(huán)境以及項(xiàng)目框架 || 下載編譯簡(jiǎn)化版Sylar)
重寫(xiě)Sylar基于協(xié)程的服務(wù)器(1、日志模塊的架構(gòu))
重寫(xiě)Sylar基于協(xié)程的服務(wù)器(2、配置模塊的設(shè)計(jì))
重寫(xiě)Sylar基于協(xié)程的服務(wù)器(3、協(xié)程模塊的設(shè)計(jì))
重寫(xiě)Sylar基于協(xié)程的服務(wù)器(4、協(xié)程調(diào)度模塊的設(shè)計(jì))
重寫(xiě)Sylar基于協(xié)程的服務(wù)器(5、IO協(xié)程調(diào)度模塊的設(shè)計(jì))
重寫(xiě)Sylar基于協(xié)程的服務(wù)器(6、HOOK模塊的設(shè)計(jì))
重寫(xiě)Sylar基于協(xié)程的服務(wù)器(7、TcpServer & HttpServer的設(shè)計(jì)與實(shí)現(xiàn))
TcpServer模塊架構(gòu)圖
將基于線程的主從Reactor模型進(jìn)行協(xié)程的定制化修改,如圖所示。
TcpServer實(shí)現(xiàn)
TcpServer類(lèi)是一個(gè)服務(wù)器通用類(lèi),TcpServer類(lèi)的實(shí)現(xiàn)是Server端專(zhuān)門(mén)用來(lái)管理Tcp連接的,主要的成員函數(shù)及作用如下:
-
構(gòu)造函數(shù),用戶在構(gòu)造一個(gè)TcpServer時(shí)會(huì)傳三個(gè)類(lèi)型都為IOManager的參數(shù),參數(shù)名以功能命名,分別是:worker、io_worker、accept_worker。
-
bind函數(shù),因?yàn)橐慌_(tái)服務(wù)器有可能有多個(gè)<ip,端口>對(duì),所以用戶在調(diào)用bind函數(shù)時(shí),可能會(huì)傳入多個(gè)地址對(duì),bind函數(shù)就是負(fù)責(zé)為這些ip地址創(chuàng)建套接字,并且將ip地址和固定端口綁定,開(kāi)始監(jiān)聽(tīng)這些套接字。
-
start函數(shù),創(chuàng)建accept協(xié)程,并將accept協(xié)程放到accept_worker協(xié)程調(diào)度器里面去,accept協(xié)程實(shí)際上就是回調(diào)函數(shù)是TcpServer::startAccept的協(xié)程。
start函數(shù)的偽代碼:
-
startAccept函數(shù),是一個(gè)接受客戶端連接的回調(diào)函數(shù),內(nèi)部是一個(gè)調(diào)用accept函數(shù)的死循環(huán),在接受到一個(gè)socketfd后,將套接字封裝成IO協(xié)程,并放入io_worker協(xié)程調(diào)度器中進(jìn)行調(diào)度。IO協(xié)程就是回調(diào)函數(shù)是TcpServer::handleClient函數(shù)的協(xié)程。
startAccept函數(shù)的偽代碼:
-
handleClient函數(shù),該函數(shù)是一個(gè)虛函數(shù),是專(zhuān)門(mén)用來(lái)和客戶請(qǐng)求對(duì)接的協(xié)程,在TcpServer中是一個(gè)簡(jiǎn)單打印連接信息的虛函數(shù),想要實(shí)現(xiàn)一個(gè)實(shí)用的服務(wù)器(如HTTP服務(wù)器、FTP服務(wù)器等)只需要對(duì)handleClient函數(shù)做定制化重寫(xiě)即可。
handleClient函數(shù)偽代碼:
HTTP服務(wù)器的實(shí)現(xiàn)
HttpServer類(lèi)繼承TcpServer類(lèi)并重寫(xiě)TcpServer::handleClient函數(shù)。
HttpServer類(lèi)重寫(xiě)了handleClient函數(shù),內(nèi)部實(shí)現(xiàn)為不斷調(diào)用recvRequest函數(shù)的死循環(huán),recvRequest函數(shù)底層會(huì)調(diào)用read函數(shù)讀取并解析客戶請(qǐng)求。在調(diào)用revcRequest函數(shù)后會(huì)將解析的請(qǐng)求提交給Servlet類(lèi)處理請(qǐng)求,Servlet層會(huì)返回回復(fù)報(bào)文,然后利用sendResponse函數(shù),將回復(fù)報(bào)文發(fā)送回客戶端。sendResponse函數(shù)底層調(diào)用write函數(shù)。
handleClient函數(shù)重寫(xiě)如下:
感興趣的同學(xué),可以閱讀一下本文實(shí)現(xiàn)的源碼:https://github.com/LunarStore/lunar
于此Sylar基礎(chǔ)模塊設(shè)計(jì)的講解完結(jié)。
除了基于協(xié)程的服務(wù)器外,推薦讀者也可以去看一下Muduo基于線程的網(wǎng)絡(luò)庫(kù)的設(shè)計(jì)。兩者對(duì)比著學(xué)習(xí)才能有更好的理解。sylar相對(duì)于Muduo來(lái)說(shuō),性能確實(shí)沒(méi)那么高,但是sylar設(shè)計(jì)的初衷是奔著框架去的,所以sylar基礎(chǔ)設(shè)施做的特別好,比如有Muduo沒(méi)有的配置模塊、動(dòng)態(tài)庫(kù)模塊、daemon模塊等,sylar另一大優(yōu)勢(shì)是對(duì)網(wǎng)絡(luò)編程友好,可以以同步的方式進(jìn)程網(wǎng)絡(luò)業(yè)務(wù)的編寫(xiě),同時(shí)享受異步的性能。而深入閱讀Muduo其實(shí)就可以發(fā)現(xiàn)Muduo網(wǎng)絡(luò)庫(kù)One Loop Per Thread的思想,和Nginx的One Loop Per Process有神奇的相似之處,這種模型,靠著每個(gè)線程都有自己的loop和任務(wù)隊(duì)列,將需要跨線程執(zhí)行的任務(wù)添加到各自的隊(duì)列中去串行執(zhí)行,加鎖的臨界區(qū)會(huì)很小,幾乎不需要鎖。所以Muduo性能很高。
Muduo源碼筆記系列:
muduo源碼閱讀筆記(0、下載編譯muduo)
muduo源碼閱讀筆記(1、同步日志)
muduo源碼閱讀筆記(2、對(duì)C語(yǔ)言原生的線程安全以及同步的API的封裝)
muduo源碼閱讀筆記(3、線程和線程池的封裝)
muduo源碼閱讀筆記(4、異步日志)
muduo源碼閱讀筆記(5、Channel和Poller)
muduo源碼閱讀筆記(6、EvevntLoop和Thread)
muduo源碼閱讀筆記(7、EventLoopThreadPool)
muduo源碼閱讀筆記(8、定時(shí)器TimerQueue)
muduo源碼閱讀筆記(9、TcpServer)
muduo源碼閱讀筆記(10、TcpConnection)
muduo源碼閱讀筆記(11、TcpClient)文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-832980.html
本章完結(jié)文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-832980.html
到了這里,關(guān)于重寫(xiě)Sylar基于協(xié)程的服務(wù)器(7、TcpServer & HttpServer的設(shè)計(jì)與實(shí)現(xiàn))的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!