1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/libhv-libhv

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
README-CN.md 12 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
gitlife-traslator Отправлено 29.11.2024 01:49 799dffd

libhv

Linux Windows macOS Android iOS

libhv — это сетевая библиотека, похожая на libevent, libev и libuv. Она предоставляет более удобный интерфейс и более богатый набор протоколов.

✨ Особенности

  • кроссплатформенность (Linux, Windows, macOS, Android, iOS, BSD, Solaris).

Примечание: в тексте запроса присутствуют ссылки, которые не были переведены. Высокопроизводительный событийный цикл (события сетевого ввода-вывода, таймера, простоя, пользовательские события, сигналы)

  • TCP/UDP сервер/клиент/прокси;
  • поддержка TCP: сердцебиение, переподключение, пересылка, многопоточная безопасность write и close;
  • встроенный распространённый режим распаковки пакетов (фиксированная длина пакета, разделитель, поле длины заголовка);
  • надёжная поддержка UDP: WITH_KCP;
  • SSL/TLS шифрование (опционально WITH_OPENSSL, WITH_GNUTLS, WITH_MBEDTLS);
  • HTTP сервер/клиент (поддержка https, http1/x, http2, grpc);
  • статические файлы, каталоги, прямой/обратный прокси, синхронный/асинхронный API обработчик;
  • RESTful стиль, маршрутизация, промежуточное ПО, keep-alive соединения, chunked блоки, SSE и другие функции;
  • WebSocket сервер/клиент;
  • MQTT клиент.

Сборка

См. BUILD.md.

libhv предоставляет следующие способы сборки:

  1. Через Makefile:
./configure
make
sudo make install
  1. Через cmake:
mkdir build
cd build
cmake ..
cmake --build .
  1. Через bazel:
bazel build libhv
  1. Через vcpkg:
vcpkg install libhv
  1. Через xmake:
xrepo install libhv

Быстрое начало работы

Опыт использования

Запустите скрипт ./getting_started.sh:

# Загрузка и компиляция
git clone https://github.com/ithewei/libhv.git
cd libhv
./configure
make

# Запуск HTTPD сервиса
bin/httpd -h
bin/httpd -d
#bin/httpd -c etc/httpd.conf -s restart -d
ps aux | grep httpd

# Сервис файлов
bin/curl -v localhost:8080

# Каталог сервиса
bin/curl -v localhost:8080/downloads/

# API сервис
bin/curl -v localhost:8080/ping
bin/curl -v localhost:8080/echo -d "hello,world!"
bin/curl -v localhost:8080/query?page_no=1\&page_size=10
bin/curl -v localhost:8080/kv   -H "Content-Type:application/x-www-form-urlencoded" -d 'user=admin&pswd=123456'
bin/curl -v localhost:8080/json -H "Content-Тип:application/json" -d '{"user":"admin","pswd":"123456"}'
bin/curl -v localhost:8080/form -F 'user=admin' -F 'pswd=123456'
bin/curl -v localhost:8080/upload -d "@LICENSE"
bin/curl -v localhost:8080/upload -F "file=@LICENSE"

bin/curl -v localhost:8080/test -H "Content-Type:application/x-www-form-urlencoded" -d 'bool=1&int=123&float=3.14&string=hello'
bin/curl -v localhost:8080/test -H "Content-Type:application/json" -d '{"bool":true,"int":123,"float":3.14,"string":"hello"}'
bin/curl -v localhost:8080/test -F 'bool=1' -F 'int=123' -F 'float=3.14' -F 'string=hello'
# RESTful API: /group/:group_name/user/:user_id
bin/curl -v -X DELETE localhost:8080/group/test/user/123

# Тестирование нагрузки
bin/wrk -c 1000 -d 10 -t 4 http://127.0.0.1:8080/

TCP

TCP сервер

C версия: examples/tcp_echo_server.c

C++ версия: evpp/TcpServer_test.cpp

#include "TcpServer.h"
using namespace hv;

int main() {
    int port = 1234;
    TcpServer srv;
    int listenfd = srv.createsocket(port);
    if (listenfd < 0) {
        return -1;
    }
    printf("server listen on port %d, listenfd=%d ...\n", port, listenfd);
    srv.onConnection = [](const SocketChannelPtr& channel) {
        std::string peeraddr = channel->peeraddr();
        if (channel->isConnected()) {
            printf("%s connected! connfd=%d\n", peeraddr.c_str(), channel->fd());
        } else {
            printf("%s disconnected! connfd=%d\n", peeraddr.c_str(), channel->fd());
        }
    };
    srv.onMessage = [](const SocketChannelPtr& channel, Buffer* buf) {
        // echo
        channel->write(buf);
    };
    srv.setThreadNum(4);
    srv.start();

    // press Enter to stop
    while (getchar() != '\n');
    return 0;
}

Обратите внимание:

Приведённые выше примеры представляют собой простой эхо-сервис, TCP является потоковым протоколом, в реальных приложениях обязательно добавьте границы для распаковки. Текстовый протокол рекомендуется добавить \0 или \r\n для разделения, см. examples/jsonrpc; Для двоичного протокола рекомендуется добавить собственный заголовок протокола, чтобы указать длину полезной нагрузки через поле длины заголовка, см. examples/protorpc; Используя setUnpack (c интерфейс — hio_set_unpack), можно установить правила распаковки, поддерживая три распространённых способа распаковки: фиксированная длина пакета, разделители и поля длины заголовка; Внутренне, в соответствии с правилами распаковки, обрабатываются пакеты с перекрытием и разделением, гарантируя, что обратный вызов onMessage получает полный пакет данных, значительно снижая затраты на обработку перекрытия и разделения на верхнем уровне. Если не хотите создавать собственный протокол и правила распаковки пакетов, можно напрямую использовать готовые протоколы HTTP/WebSocket.

channel->write (c интерфейс — hio_write) является неблокирующим (все в цикле событий асинхронного программирования должно быть неблокирующим), и многопоточно безопасным. При отправке больших объёмов данных следует осуществлять управление потоком, отслеживая событие завершения записи через onWriteComplete и отправляя следующий кадр данных при наличии возможности записи. Конкретные примеры кода см. в examples/tinyhttpd.c, где используется функция http_serve_file.

channel->close (c интерфейс — hio_close) также является многопоточно безопасным, что позволяет потокам сетевого ввода-вывода в цикле событий получать данные, распаковывать пакеты, десериализовать их и помещать в очередь, Потребительский поток/пул потоков извлекает данные из очереди, обрабатывает их, отправляет ответ и закрывает соединение, делая процесс более простым. ``` printf("onmessage: %.*s\n", (int)msg.size(), msg.data()); }; ws.onclose = { printf("onclose\n"); };

// reconnect: 1,2,4,8,10,10,10...
reconn_setting_t reconn;
reconn_setting_init(&reconn);
reconn.min_delay = 1000;
reconn.max_delay = 10000;
reconn.delay_policy = 2;
ws.setReconnect(&reconn);

ws.open("ws://127.0.0.1:9999/test");

std::string str;
while (std::getline(std::cin, str)) {
    if (!ws.isConnected()) break;
    if (str == "quit") {
        ws.close();
        break;
    }
    ws.send(str);
}

return 0;

}


```shell
# sudo apt install iperf
iperf -s -p 5001 > /dev/null &
bin/tcp_proxy_server 1212 127.0.0.1:5001 &
iperf -c 127.0.0.1 -p 5001 -l 8K
iperf -c 127.0.0.1 -p 1212 -l 8K

Пропускная способность:

------------------------------------------------------------
[  3] local 127.0.0.1 port 52560 connected with 127.0.0.1 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-10.0 sec  20.8 GBytes  17.9 Gbits/sec

------------------------------------------------------------
[  3] local 127.0.0.1 port 48142 connected with 127.0.0.1 port 1212
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-10.0 sec  11.9 GBytes  10.2 Gbits/sec

HTTP нагрузочное тестирование

# sudo apt install wrk
wrk -c 100 -t 4 -d 10s http://127.0.0.1:8080/

# sudo apt install apache2-utils
ab -c 100 -n 100000 http://127.0.0.1:8080/

libhv (порт: 8080) против nginx (порт: 80)

libhv-vs-nginx.png

Результаты тестирования можно посмотреть в Github Actions.

💎 Примеры использования

Если вы используете libhv, пожалуйста, отправьте информацию через PR в этот список, чтобы больше пользователей узнали о реальных сценариях использования libhv и помогли создать лучшую сетевую экосистему.

Пользователь (название компании/проекта/контактная информация) Пример использования (описание проекта/сценарий использования)
阅面科技 猎户AIoT平台 управление устройствами, обнаружение лиц HTTP-сервис, поиск лиц HTTP-сервис
socks5-libhv socks5 прокси
hvloop Подобно uvloop, python асинхронный IO цикл событий
tsproxyd-android Android-клиент веб-прокси-сервиса на основе libhv
玄舟智维 C100K устройство подключено к шлюзу услуг сети

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/libhv-libhv.git
git@api.gitlife.ru:oschina-mirror/libhv-libhv.git
oschina-mirror
libhv-libhv
libhv-libhv
master