Coder Social home page Coder Social logo

tutuwu2019 / anyclient Goto Github PK

View Code? Open in Web Editor NEW

This project forked from yang-jinlin/anyclient

0.0 0.0 0.0 47 KB

C++万能客户端。Http Client、Redis Client、MySQL Client、Kafka Client。极致高性能。线程安全、自带连接池、自带线程池。全异步工作模式,支持异步回调、半同步future、同步等待三套接口。可以模仿现有client开发自定义协议。

License: Apache License 2.0

C++ 85.80% Makefile 3.87% CMake 10.33%

anyclient's Introduction

AnyClient / C++万能客户端

特点

  • 极致高性能
  • 线程安全
  • 自带连接池
  • 自带线程池
  • 全异步工作模式
  • 支持异步回调、半同步future、同步等待三套接口
  • 协议无关,可以模仿现有client开发自定义协议

目录

万能客户端将世间所有编程需求规约为以下6种

网络IO

HttpClient

#include <iostream>
#include <workflow/WFFacilities.h>
#include <anyclient/WFHttpClient.h>

using namespace std;

static WFFacilities::WaitGroup wg(4);

int main(int argc, char *argv[])
{
    WFHttpClient http_client;

    http_client.default_redirect_max(5);
    http_client.default_retry_max(2);

    map<string, string> http_headers;
    http_headers["user-agent"] = "AnyClient/1.0.0";
    http_headers["cookie"] = "emotion=happy;code=simple";

    std::string http_body;

    http_body.clear();//no need http body data

//// sync
    cout << "[1]Synchronous http request start" << endl;
    auto result1 = http_client.sync_request("GET",
                                            "https://www.sogou.com",
                                            http_headers,
                                            http_body);
    cout << "[1]Synchronous http request end. HttpStaus: " << result1.status_code << endl;
    wg.done();

//// async
    cout << "[2]Semi-synchronous http request start" << endl;
    auto future = http_client.async_request("GET",
                                            "https://www.baidu.com",
                                            http_headers,
                                            http_body);
    // do anything you want
    auto result2 = future.get();
    cout << "[2]Semi-synchronous http request end. HttpStaus: " << result2.status_code << endl;
    wg.done();

//// async callback
    cout << "[3]Asynchronous http request start" << endl;
    http_client.request("GET",
                        "https://www.sogou.com",
                        http_headers,
                        http_body,
                        [](WFHttpResult& res) {
                            cout << "[3]Asynchronous http request end. HttpStaus: " << res.status_code << endl;
                            wg.done();
                        });

//// async chain
    cout << "[4]Asynchronous http request start" << endl;
    http_client.request("GET", "https://www.baidu.com")
                .set_header("user-agent", "AnyClient/1.0.0")
                .set_header("cookie", "1412")
                .success([](protocol::HttpResponse& http_resp) {
                    cout << "[4]Asynchronous http request end. HttpStaus: " << http_resp.get_status_code() << endl;
                })
                .error([](int state, int error, const std::string& errmsg) {
                    cout << "[4]Asynchronous http request end. error: " << errmsg << endl;
                })
                .complete([](WFHttpResult& res) {
                    wg.done();
                })
                .send();

    wg.wait();
    return 0;
}

RedisClient

#include <iostream>
#include <workflow/WFFacilities.h>
#include <anyclient/WFRedisClient.h>

using namespace std;

static WFFacilities::WaitGroup wg(4);

int main(int argc, char *argv[])
{
    //redis://:{password}@{host}:{port}/{db number}
    //example
    //  redis://127.0.0.1
    //  redis://:[email protected]:1122/8
    std::string redis_url = "redis://:[email protected]:6379/1";
    WFRedisClient redis_client(redis_url);

    redis_client.default_retry_max(2);

//// sync
    cout << "[1]Synchronous redis request start" << endl;
    auto result1 = redis_client.sync_request("SET", {"testkey", "testvalue"});
    cout << "[1]Synchronous redis request end. success: " << result1.success << endl;
    wg.done();

//// async
    cout << "[2]Semi-synchronous redis request start" << endl;
    auto future = redis_client.async_request("GET", {"testkey"});
    // do anything you want
    auto result2 = future.get();
    cout << "[2]Semi-synchronous redis request end." << endl;
    cout << "success: " << result2.success << endl;
    cout << "response-string: " << result2.value.string_value() << endl;
    wg.done();

//// async callback
    cout << "[3]Asynchronous redis request start" << endl;
    redis_client.request("DEL", {"testkey"}, [](WFRedisResult& res) {
                            cout << "[3]Asynchronous redis request end. success: " << res.success << endl;
                            wg.done();
                        });

//// async chain
    cout << "[4]Asynchronous redis request start" << endl;
    redis_client.request("MGET")
                .append("testkey")
                .append("somekey")
                .append("12345")
                .success([](protocol::RedisValue& val) {
                    cout << "[4]Asynchronous redis request end. success: " << val.is_ok() << endl;
                    for (size_t i = 0; i < val.arr_size(); i++)
                        cout << "[" << i << "] element-string: " << val[i].string_value() << endl;
                })
                .error([](int state, int error, const std::string& errmsg) {
                    cout << "[4]Asynchronous redis request end. error: " << errmsg << endl;
                })
                .complete([](WFRedisResult& res) {
                    wg.done();
                })
                .send();

    wg.wait();
    return 0;
}

MySQLClient

#include <iostream>
#include <workflow/WFFacilities.h>
#include <anyclient/WFMySQLClient.h>

using namespace std;

static WFFacilities::WaitGroup wg(3);

int main(int argc, char *argv[])
{
    //mysql://{username}:{password}@{host}:{port}/{db number}
    //example
    //  mysql://127.0.0.1
    //  mysql://root:[email protected]:1412/testdb
    std::string mysql_url = "mysql://127.0.0.1:3306/test";
    WFMySQLClient msyql_client(mysql_url);

    msyql_client.default_retry_max(2);
    std::string insert_query = "instert into workflow (ID, TASK_NAME, TIMESTAMP) values (1412, \"HttpTask\", NOW());";
    std::string update_query = "update workflow set TASK_NAME='GoTask' where ID=1412";
    std::string select_query = "select * from workflow where ID>=1412 limit 3";

//// sync
    cout << "[1]Synchronous mysql request start" << endl;
    auto result1 = msyql_client.sync_request(insert_query);
    cout << "[1]Synchronous mysql request end. success: " << result1.success << endl;
    wg.done();

//// async
    cout << "[2]Semi-synchronous mysql request start" << endl;
    auto future = msyql_client.async_request(update_query);
    // do anything you want
    auto result2 = future.get();
    cout << "[2]Semi-synchronous mysql request end." << endl;
    cout << "success: " << result2.success << endl;
    wg.done();

//// async callback
    cout << "[3]Asynchronous mysql request start" << endl;
    msyql_client.request(select_query, [](WFMySQLResult& res) {
                            cout << "[3]Asynchronous mysql request end. success: " << res.success << endl;

                            map<string, protocol::MySQLCell> row;
                            while (res.result_cursor.fetch_row(row))
                            {
                                cout << "---------- ROW ----------" << endl;
                                for (const auto& kv : row)
                                {
                                    const auto& cell = kv.second;
                                    cout << kv.first << ": type[" << datatype2str(cell.get_data_type()) << "] value[";
                                    if (cell.is_string() ||
                                        cell.is_date() ||
                                        cell.is_time() ||
                                        cell.is_datetime())
                                    {
                                        cout << cell.as_string();
                                    }
                                    else if (cell.is_int())
                                        cout << cell.as_int();
                                    else if (cell.is_ulonglong())
                                        cout << cell.as_ulonglong();
                                    else if (cell.is_float())
                                        cout << cell.as_float();
                                    else if (cell.is_double())
                                        cout << cell.as_double();
                                    else if (cell.is_null())
                                        cout << "NULL";
                                    else
                                        cout << cell.as_binary_string();

                                    cout << "]" << endl;
                                }

                                cout << "---------- END ----------" << endl;
                            }

                            wg.done();
                        });

    wg.wait();
    return 0;
}

KafkaClient

workflow此项功能进入开发尾声,即将开放!

磁盘IO

uint64_t write_data = 0x1234;
uint64_t read_data = 0;
ssize_t sz;
int fd = open("bio.test", O_RDWR | O_TRUNC | O_CREAT, 0644);

auto future1 = WFFacilities::async_pwrite(fd, &write_data, 8, 0);
// do anything you want
sz = future1.get();
cout << "write size = " << sz << endl;

auto future2 = WFFacilities::async_pread(fd, &read_data, 8, 0);
// do anything you want
sz = future2.get();
cout << "read size = " << sz << endl;
if (memcmp(&read_data, &write_data, 8) != 0)
    abort();

close(fd);

定时器

cout << "Semi-synchronous sleep one second start" << endl;
auto future = WFFacilities::async_usleep(1000 * 1000);
auto s = 0;
for (int i = 0; i < 1000; i++)
    s += i;

cout << "sum of 0-999: " << s << endl;
future.wait();
cout << "Semi-Synchronous sleep one second over" << endl;

计数器

#include <iostream>
#include <thread>
#include <workflow/WFFacilities.h>

using namespace std;

void thread_routine(int idx, WFFacilities::WaitGroup *wg)
{
    WFFacilities::usleep(idx * 1000 * 1000);
    cout << "thread [" << idx << "] is over" << endl;
    wg->done();//reduce waitgroup
}

int main(int argc, char *argv[])
{
    WFFacilities::WaitGroup wg(3);//Thread-Safety, need 3 times done
    std::thread *th[8];

    for (int i = 0; i < 8; i++)
        th[i] = new std::thread(thread_routine, i, &wg);

    cout << "---wait for couter" << endl;
    wg.wait();
    cout << "---couter is over" << endl;

    //wg.wait();//Reentrant for WaitGroup.wait(), can wait in any

    for (int i = 0; i < 8; i++)
    {
        th[i]->join();
        delete th[i];
    }

    return 0;
}

CPU

#include <iostream>
#include <workflow/WFFacilities.h>

using namespace std;

static WFFacilities::WaitGroup wg(8);
static int result[8];

void go_routine(int idx, int x, int y)
{
    result[idx] = x * x + y * y;
    wg.done();
}

int main(int argc, char *argv[])
{
    for (int i = 0; i < 8; i++)
        WFFacilities::go("compute", go_routine, i, i + 26, i + 62);

    cout << "---wait for compute" << endl;
    wg.wait();
    cout << "---all over" << endl;

    for (int i = 0; i < 8; i++)
        cout << "result[" << i << "] = " << result[i] << endl;

    return 0;
}

GPU

workflow此项功能目前处于闭源状态,WFCUDATask暂不开放任何源码和接口实现

AnyRPC

SogouRPC即将开源,以下功能即将开放!

Thrift Binary

Thrift Framed Transport

Thrift Http Transport

BRPC

BaiduRPC Standard

SRPC

SogouRCP Binary

SogouRCP Http

anyclient's People

Contributors

alpc62 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.