shineframe : 高性能超轻量级C++开发库及服务器编程框架

网友投稿 984 2022-10-17

shineframe : 高性能超轻量级C++开发库及服务器编程框架

shineframe : 高性能超轻量级C++开发库及服务器编程框架

shineframe : 高性能超轻量级C++开发库及服务器编程框架

一、简述

shineframe是使用c++11编写,支持(linux/windows)平台。用户通过它可以非常方便地开发非阻塞式高并发服务器程序,同时提供了一些功能库,使开发的过程变得简单高效。

shineframe使用时只需要包含.hpp头文件即可,编译时需要添加 -std=c++11选项。目前处于不断开发的过程中,功能库将会逐步丰富及持续改进。

github:https://github.com/shineframe/shineframe

技术交流群:805424758

二、库组成

shine serial 媲美protobuf的强大序列化/反序列化工具

支持c++原生对象的序列化与反序列化,是网络自定义协议格式应用的开发利器。

shine serial编解效率均高于google protobuf,提供与protobuf相似的序列化特性,如:数值压缩编码,类似于varint,序列化后体积极小(小于protobuf)。serial支持比protobuf更丰富强大的数据类型,基本的数据类型及主要STL标准容器类型字段均可进行序列化(vector, deque, list, forward_list, map, unordered_map, set, unordered_set),支持结构嵌套(注:嵌套的结构体一定也要以SHINE_SERIAL宏修饰,否则不支持,编译不通过)

shine_serial操作示例(一行代码实现c++原生对象的序列化与反序列化):

#include #include "shine_serial.hpp"struct B{ int a; double b; std::string c; //将类型名称及需要序列化的字段用SHINE_SERIAL包裹 SHINE_SERIAL(B, a, b, c);};struct A{ int a; double b; std::string c; //此处嵌套上方的结构体B std::map d; std::list e; std::vector f; std::deque g; std::forward_list h; std::set i; SHINE_SERIAL(A, a, b, c, d, e, f, g, h, i);};int main(){ A a; a.a = 123; a.b = 345.567; a.c = "hello world!"; B b; b.a = 666; b.b = 777.7777; b.c = "999999!"; a.d.emplace(999, b); a.e.emplace_back(123); a.e.emplace_back(345); a.f.emplace_back((float)12.34); a.f.emplace_back((float)45.67); a.g.emplace_back((double)456.789); a.g.emplace_back((double)78.9); a.h.emplace_front(666); a.h.emplace_front(555); a.i.emplace("A"); a.i.emplace("B"); a.i.emplace("C"); //将对象a序列化成字节流 auto data = a.shine_serial_encode(); //将字节流反序列化成对象,反序列化后a2与a中数据相同 A a2; a2.shine_serial_decode(data); //确定结果 std::cout << ((a == a2) ? "success" : "failed") << std::endl; return 0;}

执行后输出:success

json 强大的json工具

json解析类,支持字符串与json对象的互转,另外支持json字符串与c++原生对象的互转,是json协议格式应用的开发利器。

json_model操作示例(一行代码实现json字符串与c++原生对象的互转):

#include #include "util/json.hpp"using namespace shine;struct B{ int a; double b; std::string c; SHINE_JSON_MODEL(B, a, b, c);};struct A{ int a; double b; std::string c; std::map d; std::list e; std::vector f; std::deque g; std::forward_list h; std::set i; SHINE_JSON_MODEL(A, a, b, c, d, e, f, g, h, i);};int main(){ A a; a.a = 123; a.b = 345.567; a.c = "hello world!"; B b; b.a = 666; b.b = 777.7777; b.c = "999999!"; a.d.emplace(999, b); a.e.emplace_back(123); a.e.emplace_back(345); a.f.emplace_back((float)12.34); a.f.emplace_back((float)45.67); a.g.emplace_back((double)456.789); a.g.emplace_back((double)78.9); a.h.emplace_front(666); a.h.emplace_front(555); a.i.emplace("A"); a.i.emplace("B"); a.i.emplace("C"); //将对象a编码成json字符串 auto a_str = a.json_encode(); //将json字符串解码成对象,解码后a2与a中数据相同 A a2; a2.json_decode(a_str); return 0;}

json基本操作示例:

#include #include "../json.hpp"using namespace shine;int json_base_main(){ shine::string json_str = "{\ \"name\": \"\\\"BeJson\\\"\",\ \"url\": \"http://bejson.com\",\ \"page\": 33.1288,\ \"isNonProfit\": true,\ \"address\": {\ \"street\": \"科技园路.\",\ \"city\": \"江苏苏州\",\ \"country\": \"中国\"\},\\"links\": [\ {\ \"name\": \"Google\",\ \"url\": \"http://google.com\"\ },\ {\ \"name\": \"Baidu\",\ \"url\": \"http://baidu.com\"\ },\ {\ \"name\": \"SoSo\",\ \"url\": \"http://SoSo.com\"\ }\ ]\}"; shine::json json; json.decode(json_str); shine::string json_str_encode = json.encode(); shine::json json2; json_node_t node1; node1.set_key("node1"); node1.set_number("-123.345"); json2.get_root().insert_kv_child(node1); auto json2_str = json2.encode(); shine::json json3; json_node_t arr; arr.set_key("arr"); for (int i = 0; i < 5; i++) { json_node_t tmp; tmp.set_string(shine::string(i)); arr.push_back_array_child(tmp); } json3.get_root().insert_kv_child(arr); auto json3_str = json3.encode(); return 0;}

string 字符串封装

log 简单的日志实现

timer 定时器实现

pool 简单的对象池实现

redis redis客户端封装

目前只实现了同步式请求,异步式请求与请求/发布功能待完善。

简单同步客户端代码示例:

#include #include #include #include #include "../redis.hpp"using namespace shine;using namespace shine::net;int redis_main(){ shine::redis::sync redis; redis.set_addr("127.0.0.1:6379"); redis.set_recv_timeout(3000); redis.set_auth("password"); shine::string str; std::vector arr; std::set set; std::map map; redis.SET("library", "redis"); redis.GET("library", str); std::cout << str << std::endl; redis.SADD("names", "a", "b", "c", "e"); redis.SMEMBERS("names", set); for (auto &iter : set){ std::cout << iter << std::endl; } redis.KEYS("*", arr); for (auto &iter : arr){ std::cout << iter << std::endl; } redis.HSET("members", "a", "A"); redis.HSET("members", "b", "B"); redis.HSET("members", "c", "C"); redis.HGETALL("members", map); for (auto &iter : map){ std::cout << iter.first << ":" << iter.second << std::endl; } return 0;}

net 网络封装

主要封装了socket操作,提供proactor风格非阻塞套接字操作。

echo服务端示例:

#include #include "../proactor_engine.hpp"using namespace shine;using namespace shine::net;int echo_server_main(){ std::cout << "bind address: "; shine::string addr; std::cin >> addr; proactor_engine engine; bool rc = engine.add_acceptor("echo_server", addr, [&engine](bool status, connection *conn)->bool{ if (status) { conn->set_recv_timeout(0); conn->register_recv_callback([](const int8 *data, shine::size_t len, connection *conn)->bool{ conn->async_send(data, len); return true; }); conn->async_recv(); } return true; }); if (rc) { std::cout << "bind " << addr << "success." << endl; engine.run(); } else { std::cout << "bind " << addr << "failed." << endl; } return 0;}

echo客户端示例:

#include #include "../proactor_engine.hpp"using namespace shine;using namespace shine::net;int echo_client_main(){ std::cout << "connect address: "; shine::string addr; std::cin >> addr; proactor_engine engine; bool rc = engine.add_connector("client", addr, [](bool ok, connector *conn){ std::cout << "connect:" << ok << endl; if (ok) { conn->set_recv_timeout(10000); conn->register_recv_callback([](const int8 *data, shine::size_t len, connection *conn)->bool{ std::cout << "recv_callback len:" << len << " data:" << data << std::endl; conn->get_timer_manager()->set_timer(5000, [conn]()->bool{ shine::string str = "hello world!"; conn->async_send(str.data(), str.size()); return false; }); return true; }); conn->register_send_callback([](shine::size_t len, connection *conn)->bool{ return true; }); conn->register_recv_timeout_callback([](connection *conn)->bool{ std::cout << "recv_timeout_callback:" << endl; return true; }); conn->register_send_timeout_callback([](connection *conn)->bool{ std::cout << "send_timeout_callback:" << endl; return false; }); conn->register_close_callback([](connection *conn){ std::cout << "close_callback:" << endl; }); shine::string data = "hello world"; conn->async_send(data.data(), data.size()); conn->async_recv(); } }); if (rc) { std::cout << "connect " << addr << "success." << endl; engine.run(); } else { std::cout << "connect " << addr << "failed." << endl; } return 0;}

http http服务端/客户端封装

http_base_server_multi_thread示例: 在多数情况下,http服务器是需要将客户端请求分配至多个工作线组中处理的,shineframe支持这种处理方式,示例如下:

#include #include "http/http_server.hpp"using namespace shine;using namespace shine::net;using namespace http;int main(){ proactor_engine engine; shine::string addr = "0.0.0.0:38300"; http::server_peer_multi_thread::setup(engine); bool rc = engine.add_acceptor("http_base_server", addr, [&engine](bool status, connection *conn)->bool{ if (status) { http::server_peer_multi_thread *conn_handle = new http::server_peer_multi_thread; conn_handle->set_recv_timeout(15000); conn_handle->register_url_handle("/", [](const http::request &request, http::response &response)->bool{ http::entry_t allow; allow.set_key("Access-Control-Allow-Origin"); allow.set_value("*"); response.add_entry(allow); response.set_version(request.get_version()); response.set_status_code(200); response.set_body("hello shineframe!"); std::cout << "handle thread: " << std::this_thread::get_id() << std::endl; return true; }); conn_handle->register_url_handle("/api/hello", [](const http::request &request, http::response &response)->bool{ response.set_version(request.get_version()); response.set_status_code(200); shine::string body = "hello api!\r\n\r\nparameters:\r\n"; for (auto pa : request.get_url_parameters()) { body += pa.first + "=" + pa.second + "\r\n"; } response.set_body(body); return true; }); conn_handle->run(conn); } return true; }); if (rc) { std::cout << "bind " << addr << "success." << endl; engine.run(); } else { std::cout << "bind " << addr << "failed." << endl; } return 0;}

http_base_server示例:

#include #include "../http_server.hpp"using namespace shine;using namespace shine::net;using namespace http;int base_server_main(){ proactor_engine engine; shine::string addr = "0.0.0.0:8300"; bool rc = engine.add_acceptor("http_base_server", addr, [&engine](bool status, connection *conn)->bool{ if (status) { http::server_peer *conn_handle = new http::server_peer; conn_handle->set_recv_timeout(15000); conn_handle->register_url_handle("/", [](const http::request &request, http::response &response)->bool{ response.set_version(request.get_version()); response.set_status_code(200); response.set_body("hello shineframe!"); return true; }); conn_handle->register_url_handle("/api/*", [](const http::request &request, http::response &response)->bool{ response.set_version(request.get_version()); response.set_status_code(200); shine::string body = "hello api!\r\n\r\nparameters:\r\n"; for (auto pa : request.get_url_parameters()) { body += pa.first + "=" + pa.second + "\r\n"; } response.set_body(body); return true; }); conn_handle->run(conn); } return true; }); if (rc) { std::cout << "bind " << addr << "success." << endl; engine.run(); } else { std::cout << "bind " << addr << "failed." << endl; } return 0;}

http_base_client抓取页面示例:

#include #include "../http_client.hpp"using namespace shine;using namespace shine::net;using namespace http;int base_client_main(){ sync_client clinet; clinet.set_recv_timeout(3000); clinet.get_request().set_host("baidu.com"); clinet.get_request().set_method(http::method::get); clinet.get_request().set_url("/"); if (clinet.call()) { shine::string tmp; clinet.get_response().encode(tmp); std::cout << tmp << std::endl; } else { std::cout << "" << std::endl; } return 0;}

mysql封装

封装了mysql c api,提供常用的数据库访问接口。

#include #include "db/mysql.hpp"using namespace shine;using namespace shine::db;int main(){ db::mysql_connect_info connect_info; connect_info.set_addr("172.10.4.19:3306"); connect_info.set_user("root"); connect_info.set_password("root"); connect_info.set_database("tmp"); shine::db::mysql_pool pool(connect_info); auto conn = pool.get(); conn->execute("DROP TABLE IF EXISTS students"); conn->execute("CREATE TABLE `students` (\ `id` int(11) NOT NULL AUTO_INCREMENT,\ `name` varchar(32) NOT NULL,\ `age` int(4) NOT NULL,\ PRIMARY KEY(`id`)\ )"); shine::string sql = "INSERT INTO `students` (`id`, `name`, `age`) VALUES "; for (int i = 1; i <= 100; i++) { if (i > 1) sql.append(","); sql.format_append("(%d, 'name_%d', %d) ", i, i, i); } conn->execute(sql); db::mysql_result result; conn->select("SELECT * FROM students", &result); result.foreach_colmuns([](shine::size_t index, const shine::string &name){ std::cout << name << " "; }); std::cout << std::endl; shine::size_t row_num = -1; result.foreach_rows([&row_num](shine::size_t row, shine::size_t column_num, const shine::string &column_name, const shine::string &value){ if (row_num != row) { row_num = row; std::cout << std::endl; } std::cout<< value << " "; }); return 0;}

websocket服务端封装

echo服务端代码示例:

#include #include "websocket/websocket_server.hpp"using namespace shine;using namespace shine::net;using namespace websocket;int main(){ proactor_engine engine; shine::string addr = "0.0.0.0:8300"; bool rc = engine.add_acceptor("websocket_echo_server", addr, [&engine](bool status, connection *conn)->bool{ if (status) { websocket::server_peer *conn_handle = new websocket::server_peer; conn_handle->set_recv_timeout(0); conn_handle->register_recv_callback([](frame_type type, const int8 *data, shine::size_t len, net::connection *conn)->bool{ if (type == websocket::e_text) { shine::string response = parser::encode(type, data, len); conn->async_send(response.data(), response.size()); } else if (type == websocket::e_binary) { shine::string response = parser::encode(type, data, len); conn->async_send(response.data(), response.size()); } return true; }); conn_handle->register_close_callback([](net::connection *conn){ std::cout << "websocket_close_callback:" << conn << std::endl; }); conn_handle->run(conn); } return true; }); if (rc) { std::cout << "bind " << addr << "success." << endl; engine.run(); } else { std::cout << "bind " << addr << "failed." << endl; } return 0;}

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:序列化标注框架,利用pytorch实现了高效的数据加载模块
下一篇:聊聊c++中的set
相关文章

 发表评论

暂时没有评论,来抢沙发吧~