溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

怎么使用jwEngine框架

發(fā)布時(shí)間:2021-10-18 10:27:37 來(lái)源:億速云 閱讀:137 作者:柒染 欄目:web開(kāi)發(fā)

本篇文章為大家展示了怎么使用jwEngine框架,內(nèi)容簡(jiǎn)明扼要并且容易理解,絕對(duì)能使你眼前一亮,通過(guò)這篇文章的詳細(xì)介紹希望你能有所收獲。

jwEngine

一個(gè)跨平臺(tái)的c++<->lua服務(wù)器快速解決方案,該框架即可快速響應(yīng)服務(wù)器開(kāi)發(fā)工作,設(shè)計(jì)思想:“讓事情變得更簡(jiǎn)單”

網(wǎng)絡(luò)底層采用libuv(node.js底層庫(kù)),異步io助力使單線(xiàn)程也能釋放澎湃動(dòng)力,跨平臺(tái)支持epoll、iocp、ipv6。框架支持tcp、udp/kcp、websocket、http,并保證了接口的一致性,使用了sol2將所有接口都導(dǎo)出到lua,可以選擇用lua開(kāi)發(fā)邏輯。

使用modern c++開(kāi)發(fā),盡可能的使用std::move、std::string_view減少內(nèi)存復(fù)制。

該框架使用異步事件,不建議使用多線(xiàn)程,避免多線(xiàn)程上下文切換開(kāi)銷(xiāo)和破壞代碼美感,網(wǎng)絡(luò)部分和邏輯部分使用一個(gè)主事件循環(huán)驅(qū)動(dòng)。建議的方案是多進(jìn)程單線(xiàn)程的橫向擴(kuò)展,按照業(yè)務(wù)控制各個(gè)進(jìn)程的粒度,當(dāng)然mysqlredis可以加入到線(xiàn)程池中。

創(chuàng)建一個(gè)tcp服務(wù)器

只需要簡(jiǎn)單幾行代碼即可創(chuàng)建一個(gè)tcp高性能服務(wù)器,并自動(dòng)處理數(shù)據(jù)包頭和粘包(其中包頭包含消息長(zhǎng)度和協(xié)議號(hào)),構(gòu)建一個(gè)完好的NetPacket交給你。

class INetEvent : public NetEvent { public:   virtual void onAccept(NetConnect * conn){}   virtual void onClose(NetConnect * conn){}   virtual void onMsg(NetConnect * conn, int msgtype, NetPacket * pack){} };  int main() {   EventLoop::Instance()->init();    INetEvent eve;   NetServer server(EventLoop::Instance(), &eve);   server.listen("127.0.0.1", 3001);    return EventLoop::Instance()->run(); }

創(chuàng)建一個(gè)kcp服務(wù)器

c++的kcp服務(wù)器示例,快速構(gòu)建你的幀同步服務(wù)器,保證消息的可靠性

class KNetEvent : public KcpEvent { public:   virtual void onAccept(KcpSession * conn){};   virtual void onClose(KcpSession * conn){};   virtual void onMsg(KcpSession * conn, int msgtype, UdpPacket * pack){}   virtual void onUdpTimeout(KcpSession * s){} };  int main() {   EventLoop::Instance()->init();    KNetEvent eve;   KcpServer server(EventLoop::Instance(), &eve);   server.start("127.0.0.1", 3001);    return EventLoop::Instance()->run(); }

創(chuàng)建一個(gè)websocket服務(wù)器

自動(dòng)完成解析websocket協(xié)議工作

class IWebEvent : public WebSocketEvent { public:   virtual void onHandshake(WebSocketConnect * conn){};   virtual void onAccept(WebSocketConnect * conn){};   virtual void onClose(WebSocketConnect * conn){};   virtual void onMsg(WebSocketConnect * conn, WebSocketPacket * pack){}; };  int main() {   EventLoop::Instance()->init();    IWebEvent wevent;   WebSocketServer server(EventLoop::Instance(), &wevent);   server.listen("127.0.0.1", 8080);    return EventLoop::Instance()->run(); }

創(chuàng)建一個(gè)http服務(wù)器

http僅支持簡(jiǎn)單的get post請(qǐng)求

const char * html = R"(<html> <body> <h2>login</h2> <p>hello world!</p>   <form action="login" method="post">     <input type="text" name="user"/>     <input type="password" name="pass"/>     <input type="submit" value="login"/>   </form> </body> </html>)";    const char * succeed = "" "<html>" "<body>" "<h2>login succeed</h2>" "</body>" "</html>";  const char * failing = "" "<html>" "<body>" "<h2>login failing</h2>" "</body>" "</html>";  int main() {   EventLoop::Instance()->init();   HttpServer server(EventLoop::Instance());   server.listen("127.0.0.1", 80);    server.addGet("/", [](HttpConnect *conn, std::string_view & data) {     conn->autoMsg(html);   });    server.addPost("/login", [](HttpConnect *conn, std::string_view & data) {     HttpParam hp(data);     if (hp.getStr("user") == "jw" && hp.getStr("pass") == "1111")     {       conn->autoMsg(succeed);     }     else     {       conn->autoMsg(failing);     }   });    return EventLoop::Instance()->run(); }

mysql和線(xiàn)程池

這次我們用lua示例:

local config = DBConfig:new() config.device = "mysql" config.ip = "127.0.0.1" config.dbname = "jw_test" config.user = "root" config.pswd = "1111" config.port = 3306  pool = DBThreadPool:new(config) pool:create(1)  func = function(err, result)   while(result:fetch())   do     local id = result:getInt32()     local num = result:getInt32()     local name = result:getString()      local str = "id:" .. id .. ", num:" .. num .. ", name:" .. name     print(str)   end end  function exec()   local sql = SqlCommand:new("select * from test where id = ?")   sql:pushInt32(1)   sql:addToPool(pool, func) end  event_init() exec() timer = UTimer:new() timer:start(function ()     pool:update()   end, 10, 10) event_run()

任意擴(kuò)展進(jìn)程節(jié)點(diǎn)

你可以任意擴(kuò)展你的進(jìn)程,示例:

base進(jìn)程cell進(jìn)程db進(jìn)程
start engine.exe base.luastart engine.exe cell.luastart engine.exe db.lua

提供一個(gè)serialization序列化工具

類(lèi)似于c++的語(yǔ)法,寫(xiě)起來(lái)非常簡(jiǎn)單,示例:

struct testmsg {   int32 x   int32 y   int32 z   int8 state   vector<int32> vec      read{     [x, y, z, state]     if(state == 1)     {       [vec]     }   }   write{     [x, y, z, state, vec]   } }

通過(guò)serialization工具可以將協(xié)議的描述文件生成c++和lua代碼,自動(dòng)生成read()和write()的函數(shù)實(shí)現(xiàn),使得數(shù)據(jù)結(jié)構(gòu)快速映射到SocketBuffer中。

目前serialization序列化工具為實(shí)驗(yàn)性,可能是脆弱的,建議使用更強(qiáng)大的protobuf。該項(xiàng)目已集成lua-protobuf,使得c++和lua之間的協(xié)議無(wú)縫銜接。

lua-protobuf的開(kāi)源地址: lua-protobuf

這個(gè)示例展示了c++客戶(hù)端和lua服務(wù)器之間的通訊: 快速搭建服務(wù)器Demo

構(gòu)建

你需要一個(gè)modern c++17編譯器

  • vs2017 測(cè)試通過(guò)

  • gcc version 9.3.0 測(cè)試通過(guò)

上述內(nèi)容就是怎么使用jwEngine框架,你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI