### Quick Start: Download and Build libhv
Source: https://github.com/ithewei/libhv/blob/master/README-CN.md
Initial steps to get started with libhv, including cloning the repository, configuring, and compiling the library.
```shell
git clone https://github.com/ithewei/libhv.git
cd libhv
./configure
make
```
--------------------------------
### Getting Started with libhv
Source: https://github.com/ithewei/libhv/blob/master/README.md
Basic steps to clone, build, and run the httpd server. Includes examples for testing different httpd services.
```shell
git clone https://github.com/ithewei/libhv.git
cd libhv
./configure
make
bin/httpd -h
bin/httpd -d
#bin/httpd -c etc/httpd.conf -s restart -d
ps aux | grep httpd
```
--------------------------------
### Build and Run Full HTTP Server Example (Shell)
Source: https://github.com/ithewei/libhv/wiki/中文教程
Shell commands to clone the libhv repository, build the httpd and curl examples, and start the httpd server.
```shell
git clone https://github.com/ithewei/libhv.git
cd libhv
make httpd curl
bin/httpd -h
bin/httpd -d
#bin/httpd -c etc/httpd.conf -s restart -d
ps aux | grep httpd
```
--------------------------------
### HTTP Benchmark Tools
Source: https://github.com/ithewei/libhv/wiki/中文教程
Examples of using ApacheBench (ab) and wrk for HTTP load testing. Ensure the respective utilities are installed before running.
```shell
sudo apt install apache2-utils
ab -c 100 -n 100000 http://127.0.0.1:8080/
```
```shell
sudo apt install wrk
wrk -c 100 -t 4 -d 10s http://127.0.0.1:8080/
```
--------------------------------
### WebSocket Client Example
Source: https://github.com/ithewei/libhv/blob/master/README.md
Demonstrates how to implement a WebSocket client using libhv. Includes setup for connection, message handling, and reconnection logic. Use this for real-time bidirectional communication.
```c++
#include "WebSocketClient.h"
using namespace hv;
int main(int argc, char** argv) {
WebSocketClient ws;
ws.onopen = []() {
printf("onopen\n");
};
ws.onmessage = [](const std::string& msg) {
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;
}
```
--------------------------------
### Install Protobuf
Source: https://github.com/ithewei/libhv/wiki/中文教程
Follow these shell commands to clone the protobuf repository, configure, build, and install it on your system. Verify the installation using 'which protoc' and 'protoc -h'.
```shell
git clone https://github.com/protocolbuffers/protobuf
cd protobuf
./autogen.sh
./configure
make
sudo make install
sudo ldconfig
which protoc
protoc -h
```
--------------------------------
### Configure and Build libhv with Makefile
Source: https://github.com/ithewei/libhv/blob/master/CLAUDE.md
Use this Makefile to configure build options, build the library and examples, run tests, and install the library. Ensure dependencies like OpenSSL are specified during configuration.
```bash
./configure --with-openssl --with-http --with-mqtt --with-kcp # configure options
make libhv # build library only (shared + static)
make # build library + examples
make examples # build all example programs
make unittest # compile unit tests
make evpp # build C++ evpp tests (requires libhv built first)
make clean # clean build artifacts
sudo make install # install to /usr/local/include/hv and /usr/local/lib
```
--------------------------------
### libhv Example Program
Source: https://github.com/ithewei/libhv/wiki/中文教程
This C code demonstrates how to include the main libhv header, retrieve the library's compile version, and get the executable's file path and run directory. It uses libhv's logging functions.
```c
#include "hv/hv.h"
int main() {
char exe_filepath[MAX_PATH] = {0};
char run_dir[MAX_PATH] = {0};
// 获取hv编译版本
const char* version = hv_compile_version();
// 获取可执行文件路径
get_executable_path(exe_filepath, sizeof(exe_filepath));
// 获取运行目录
get_run_dir(run_dir, sizeof(run_dir));
printf("exe_filepath=%s\n", exe_filepath);
printf("run_dir=%s\n", run_dir);
// 写日志
LOGI("libhv version: %s", version);
return 0;
}
```
--------------------------------
### Start protorpc Server
Source: https://github.com/ithewei/libhv/wiki/中文教程
Command to start the protorpc server listening on a specified port.
```bash
$ bin/protorpc_server 1234
protorpc_server listen on port 1234, listenfd=3 ...
```
--------------------------------
### libhv HTTP Server Setup and Control
Source: https://github.com/ithewei/libhv/wiki/中文教程
Commands to build and manage the libhv HTTP server. This includes cloning the repository, compiling the server and client tools, and starting the server in different modes.
```shell
git clone https://github.com/ithewei/libhv.git
cd libhv
make httpd curl
```
```shell
bin/httpd -h
```
```shell
bin/httpd -d
```
```shell
#bin/httpd -c etc/httpd.conf -s restart -d
```
```shell
ps aux | grep httpd
```
--------------------------------
### C UDP Client Example
Source: https://github.com/ithewei/libhv/wiki/中文教程
A C example demonstrating how to create a UDP client using libhv. It includes setting up a timer to send data and handling received messages.
```c
#include "hv/hloop.h"
#include "hv/htime.h"
void on_timer(htimer_t* timer) {
char str[DATETIME_FMT_BUFLEN] = {0};
datetime_t dt = datetime_now();
datetime_fmt(&dt, str);
printf("> %s\n", str);
// 获取userdata
hio_t* io = (hio_t*)hevent_userdata(timer);
// 发送时间字符串
hio_write(io, str, strlen(str));
}
void on_recvfrom(hio_t* io, void* buf, int readbytes) {
printf("< %.*s\n", readbytes, (char*)buf);
}
int main(int argc, char** argv) {
if (argc < 2) {
printf("Usage: cmd port\n");
return -10;
}
int port = atoi(argv[1]);
// 创建事件循环
hloop_t* loop = hloop_new(0);
// 创建UDP客户端
hio_t* io = hloop_create_udp_client(loop, "127.0.0.1", port);
if (io == NULL) {
return -20;
}
// 设置read回调
hio_setcb_read(io, on_recvfrom);
// 开始读
hio_read(io);
// 添加一个定时器
htimer_t* timer = htimer_add(hevent_loop(io), on_timer, 1000, INFINITE);
// 设置userdata
hevent_set_userdata(timer, io);
// 运行事件循环
hloop_run(loop);
// 释放事件循环
hloop_free(&loop);
return 0;
}
```
--------------------------------
### Install libhv with Xmake
Source: https://github.com/ithewei/libhv/blob/master/README.md
Install libhv using the xmake build tool.
```shell
xrepo install libhv
```
--------------------------------
### Create Examples Target
Source: https://github.com/ithewei/libhv/blob/master/examples/CMakeLists.txt
This CMake snippet creates a custom target named 'examples' that depends on all the example executables defined previously. This allows building all examples with a single command.
```cmake
add_custom_target(examples DEPENDS ${EXAMPLES})
```
--------------------------------
### kcptun Server Example with Encryption and Compression Disabled
Source: https://github.com/ithewei/libhv/blob/master/examples/kcptun/README.md
An example of running the kcptun server with specific parameters to disable encryption, compression, and fec. This is useful for testing or specific network environments.
```shell
golang_kcptun_server -l :4000 -t 127.0.0.1:1234 --mode fast3 --crypt null --nocomp --ds 0 --ps 0
```
--------------------------------
### Install libhv with Vcpkg
Source: https://github.com/ithewei/libhv/blob/master/README.md
Install libhv using the vcpkg package manager.
```shell
vcpkg install libhv
```
--------------------------------
### JSON-RPC Server Output Example
Source: https://github.com/ithewei/libhv/wiki/中文教程
This output shows the server's console logs when it starts listening and handles an incoming 'add' request, including the received JSON and the sent response.
```shell
$ bin/jsonrpc_server 1234
listenfd=4
on_accept connfd=7
> {"id":1,"method":"add","params":[1,2]}
< {"id":1,"result":3}
on_close fd=7 error=0
```
--------------------------------
### curl command-line usage and examples
Source: https://github.com/ithewei/libhv/wiki/中文教程
Shows the command-line options and usage examples for the libhv curl client. Useful for testing HTTP endpoints and understanding request formatting.
```shell
bin/curl -h
Usage: curl [hVvX:H:d:F:n:] url
Options:
-h|--help Print this message.
-V|--version Print version.
-v|--verbose Show verbose infomation.
-X|--method Set http method.
-H|--header Add http headers, -H "Content-Type:application/json Accept:*/*"
-d|--data Set http body.
-F|--form Set http form, -F "name1=content;name2=@filename"
-n|--count Send request count, used for test keep-alive
--http2 Use http2
--grpc Use grpc over http2
Examples:
curl -v localhost:8080
curl -v localhost:8080/hello
curl -v localhost:8080/query?page_no=1&page_size=10
curl -v localhost:8080/echo -d 'hello,world!'
curl -v localhost:8080/kv -H "Content-Type:application/x-www-form-urlencoded" -d 'user=admin&pswd=123456'
curl -v localhost:8080/json -H "Content-Type:application/json" -d '{"user":"admin","pswd":"123456"}'
curl -v localhost:8080/form -F 'file=@filename'
```
--------------------------------
### C++ UDP Client Example
Source: https://github.com/ithewei/libhv/wiki/中文教程
A C++ example for creating a UDP client using libhv's UdpClient class. It demonstrates setting up message handlers and sending data periodically.
```cpp
#include "hv/UdpClient.h"
#include "hv/htime.h"
using namespace hv;
int main(int argc, char* argv[]) {
if (argc < 2) {
printf("Usage: %s port\n", argv[0]);
return -10;
}
int port = atoi(argv[1]);
UdpClient cli;
int sockfd = cli.createsocket(port);
if (sockfd < 0) {
return -20;
}
printf("client sendto port %d, sockfd=%d ...\n", port, sockfd);
cli.onMessage = [](const SocketChannelPtr& channel, Buffer* buf) {
printf("< %.*s\n", (int)buf->size(), (char*)buf->data());
};
cli.onWriteComplete = [](const SocketChannelPtr& channel, Buffer* buf) {
printf("> %.*s\n", (int)buf->size(), (char*)buf->data());
};
cli.start();
// sendto(time) every 3s
cli.loop()->setInterval(3000, [&cli](TimerID timerID) {
char str[DATETIME_FMT_BUFLEN] = {0};
datetime_t dt = datetime_now();
datetime_fmt(&dt, str);
cli.sendto(str);
});
while (1) sleep(1);
return 0;
}
```
--------------------------------
### Running libhv httpd and curl
Source: https://github.com/ithewei/libhv/wiki/中文教程
Demonstrates how to start the libhv httpd server and then test it with the libhv curl client. Ensure you have executed the getting_started.sh script first.
```shell
./getting_started.sh
Welcome to libhv!
Press any key to run ...
bin/httpd -c etc/httpd.conf -s restart -d
httpd start/running
hw 83110 0.0 0.0 5100160 588 ?? S 4:14下午 0:00.00 httpd: worker process
hw 83109 0.0 0.0 4951680 580 ?? S 4:14下午 0:00.00 httpd: worker process
hw 83108 0.0 0.0 4820608 572 ?? S 4:14下午 0:00.00 httpd: worker process
hw 83107 0.0 0.0 4689536 600 ?? S 4:14下午 0:00.00 httpd: worker process
hw 83103 0.0 0.0 4950656 808 ?? Ss 4:14下午 0:00.00 httpd: master process
bin/curl -v localhost:8080
GET / HTTP/1.1
Accept: */*
Connection: keep-alive
Content-Length: 0
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 130
Content-Type: text/html
Date: Fri, 05 Feb 2021 08:14:14 GMT
Etag: "5fc1057e-82"
Last-Modified: Fri, 27 Nov 2020 13:56:14 GMT
Server: httpd/1.21.2.5
httpd
Welcome to httpd!
```
--------------------------------
### Build libhv with Make
Source: https://github.com/ithewei/libhv/blob/master/README.md
Standard build process using Make. Ensure you have the necessary build tools installed.
```shell
./configure
make
sudo make install
```
--------------------------------
### Install libhv with Package Managers
Source: https://github.com/ithewei/libhv/blob/master/CLAUDE.md
Install libhv using vcpkg or xrepo package managers. These commands handle dependency management and installation.
```bash
vcpkg install libhv # vcpkg
xrepo install libhv # xmake
```
--------------------------------
### Compiling and Running the libhv Example
Source: https://github.com/ithewei/libhv/wiki/中文教程
This shows the shell commands to compile the test C program using the libhv library and then execute it. It also demonstrates how to view the generated log file.
```shell
$ cc -std=c99 test.c -o test -lhv
$ ./test
exe_filepath=/home/hw/github/libhv/test
run_dir=/home/hw/github/libhv
$ cat libhv*.log
2021-02-06 00:16:40.989 INFO libhv version: 1.21.1.31 [test.c:19:main]
```
--------------------------------
### JSON-RPC Client Example in Shell
Source: https://github.com/ithewei/libhv/wiki/中文教程
These shell commands demonstrate how to build and run the JSON-RPC client and server, and how to make various RPC calls (add, divide, and a non-existent method).
```shell
git clone https://github.com/ithewei/libhv
cd libhv
make jsonrpc
# mkdir build && cd build && cmake .. && cmake --build . --target jsonrpc
bin/jsonrpc_server 1234
bin/jsonrpc_client 127.0.0.1 1234 add 1 2
bin/jsonrpc_client 127.0.0.1 1234 div 1 0
bin/jsonrpc_client 127.0.0.1 1234 xyz 1 2
```
--------------------------------
### Run ab for Web Server Benchmarking
Source: https://github.com/ithewei/libhv/blob/master/README.md
Use ApacheBench (ab) to benchmark a web server. Ensure apache2-utils is installed before running.
```shell
sudo apt install apache2-utils
ab -c 100 -n 100000 http://127.0.0.1:8080/
```
--------------------------------
### Run wrk for Web Server Benchmarking
Source: https://github.com/ithewei/libhv/blob/master/README.md
Use the wrk tool to benchmark a web server. Ensure wrk is installed before running.
```shell
sudo apt install wrk
wrk -c 100 -t 4 -d 10s http://127.0.0.1:8080/
```
--------------------------------
### C++ TCP Client Example
Source: https://github.com/ithewei/libhv/wiki/中文教程
Demonstrates setting up a TCP client in C++ using libhv. It includes connection, message handling, and write completion callbacks. Reconnection policies can be configured.
```cpp
#include "hv/TcpClient.h"
#include "hv/htime.h"
using namespace hv;
int main(int argc, char* argv[]) {
if (argc < 2) {
printf("Usage: %s port\n", argv[0]);
return -10;
}
int port = atoi(argv[1]);
TcpClient cli;
int connfd = cli.createsocket(port);
if (connfd < 0) {
return -20;
}
printf("client connect to port %d, connfd=%d ...\n", port, connfd);
cli.onConnection = [](const SocketChannelPtr& channel) {
std::string peeraddr = channel->peeraddr();
if (channel->isConnected()) {
printf("connected to %s! connfd=%d\n", peeraddr.c_str(), channel->fd());
// send(time) every 3s
setInterval(3000, [channel](TimerID timerID){
if (channel->isConnected()) {
char str[DATETIME_FMT_BUFLEN] = {0};
datetime_t dt = datetime_now();
datetime_fmt(&dt, str);
channel->write(str);
} else {
killTimer(timerID);
}
});
} else {
printf("disconnected to %s! connfd=%d\n", peeraddr.c_str(), channel->fd());
}
};
cli.onMessage = [](const SocketChannelPtr& channel, Buffer* buf) {
printf("< %.*s\n", (int)buf->size(), (char*)buf->data());
};
cli.onWriteComplete = [](const SocketChannelPtr& channel, Buffer* buf) {
printf("> %.*s\n", (int)buf->size(), (char*)buf->data());
};
// reconnect: 1,2,4,8,10,10,10...
ReconnectInfo reconn;
reconn.min_delay = 1000;
reconn.max_delay = 10000;
reconn.delay_policy = 2;
cli.setReconnect(&reconn);
cli.start();
while (1) sleep(1);
return 0;
}
```
--------------------------------
### JavaScript WebSocket Client Example
Source: https://github.com/ithewei/libhv/wiki/中文教程
This JavaScript code provides a basic example of a WebSocket client. It establishes a connection, sends a 'hello' message upon opening, logs received messages, and alerts when the connection is closed. This can be used with a compatible WebSocket server.
```js
function WebSocketTest(url) {
var ws = new WebSocket(url);
ws.onopen = function() {
alert("连接已建立");
ws.send("hello");
};
ws.onmessage = function(ev) {
var received_msg = ev.data;
console.log("received websocket message: " + received_msg);
};
ws.onclose = function() {
alert("连接已关闭");
};
}
```
--------------------------------
### Set and Get Hostname
Source: https://github.com/ithewei/libhv/blob/master/docs/cn/hloop.md
Configure and retrieve the hostname for SSL/TLS connections.
```c
// 设置主机名
int hio_set_hostname(hio_t* io, const char* hostname);
// 获取主机名
const char* hio_get_hostname(hio_t* io);
```
--------------------------------
### Run httpd service
Source: https://github.com/ithewei/libhv/blob/master/README-CN.md
Commands to start and manage the httpd service. Use `ps aux | grep httpd` to check the process.
```bash
bin/httpd -h
```
```bash
bin/httpd -d
```
--------------------------------
### kcptun Test Scenario
Source: https://github.com/ithewei/libhv/blob/master/examples/kcptun/README.md
Demonstrates a full test setup involving a TCP client, kcptun client, kcptun server, and TCP server. Configure each component with the specified addresses and modes.
```shell
tcp_server: bin/tcp_echo_server 1234
kcptun_server: bin/kcptun_server -l :4000 -t 127.0.0.1:1234 --mode fast3
nc 127.0.0.1 8388
> hello
< hello
```
```shell
kcptun_client: bin/kcptun_client -l :8388 -r 127.0.0.1:4000 --mode fast3
```
--------------------------------
### libhv Curl Client Examples
Source: https://github.com/ithewei/libhv/wiki/中文教程
Demonstrates various ways to use the libhv curl client to interact with a running HTTP server. Examples include accessing different endpoints, sending data with various content types (form, JSON), and performing a DELETE request.
```shell
bin/curl -v localhost:8080
```
```shell
bin/curl -v localhost:8080/downloads/
```
```shell
bin/curl -v localhost:8080/ping
```
```shell
bin/curl -v localhost:8080/echo -d "hello,world!"
```
```shell
bin/curl -v localhost:8080/query?page_no=1\&page_size=10
```
```shell
bin/curl -v localhost:8080/kv -H "Content-Type:application/x-www-form-urlencoded" -d 'user=admin&pswd=123456'
```
```shell
bin/curl -v localhost:8080/json -H "Content-Type:application/json" -d '{"user":"admin","pswd":"123456"}'
```
```shell
bin/curl -v localhost:8080/form -F "user=admin pswd=123456"
```
```shell
bin/curl -v localhost:8080/upload -F "file=@LICENSE"
```
```shell
bin/curl -v localhost:8080/test -H "Content-Type:application/x-www-form-urlencoded" -d 'bool=1&int=123&float=3.14&string=hello'
```
```shell
bin/curl -v localhost:8080/test -H "Content-Type:application/json" -d '{"bool":true,"int":123,"float":3.14,"string":"hello"}'
```
```shell
bin/curl -v localhost:8080/test -F 'bool=1 int=123 float=3.14 string=hello'
```
```shell
# RESTful API: /group/:group_name/user/:user_id
bin/curl -v -X DELETE localhost:8080/group/test/user/123
```
--------------------------------
### Setup UDP Upstream Forwarding
Source: https://github.com/ithewei/libhv/blob/master/docs/cn/hloop.md
Establishes UDP forwarding to a specified host and port. Returns the upstream I/O object.
```c
hio_t* hio_setup_udp_upstream(hio_t* io, const char* host, int port);
```
--------------------------------
### C Example: One Acceptor + Multi-Worker Threads
Source: https://github.com/ithewei/libhv/wiki/中文教程
This C code implements a server with one thread accepting connections and distributing them to multiple worker threads. It uses `hloop_post_event` for thread-safe communication between the acceptor and worker threads. Compile with `make examples` and run the server with `bin/one-acceptor-multi-workers `.
```c
#include "hloop.h"
#include "hsocket.h"
#include "hthread.h"
static const char* host = "0.0.0.0";
static int port = 1234;
static int thread_num = 4;
static hloop_t* accept_loop = NULL;
static hloop_t** worker_loops = NULL;
static hloop_t* get_next_loop() {
static int s_cur_index = 0;
if (s_cur_index == thread_num) {
s_cur_index = 0;
}
return worker_loops[s_cur_index++];
}
static void on_close(hio_t* io) {
printf("on_close fd=%d error=%d\n", hio_fd(io), hio_error(io));
}
static void on_recv(hio_t* io, void* buf, int readbytes) {
// echo
hio_write(io, buf, readbytes);
}
static void new_conn_event(hevent_t* ev) {
hloop_t* loop = ev->loop;
hio_t* io = (hio_t*)hevent_userdata(ev);
hio_attach(loop, io);
char localaddrstr[SOCKADDR_STRLEN] = {0};
char peeraddrstr[SOCKADDR_STRLEN] = {0};
printf("tid=%ld connfd=%d [%s] <= [%s]\n",
(long)hv_gettid(),
(int)hio_fd(io),
SOCKADDR_STR(hio_localaddr(io), localaddrstr),
SOCKADDR_STR(hio_peeraddr(io), peeraddrstr));
hio_setcb_close(io, on_close);
hio_setcb_read(io, on_recv);
hio_read(io);
}
static void on_accept(hio_t* io) {
hio_detach(io);
hloop_t* worker_loop = get_next_loop();
hevent_t ev;
memset(&ev, 0, sizeof(ev));
ev.loop = worker_loop;
ev.cb = new_conn_event;
ev.userdata = io;
hloop_post_event(worker_loop, &ev);
}
static HTHREAD_RETTYPE worker_thread(void* userdata) {
hloop_t* loop = (hloop_t*)userdata;
hloop_run(loop);
return 0;
}
static HTHREAD_RETTYPE accept_thread(void* userdata) {
hloop_t* loop = (hloop_t*)userdata;
hio_t* listenio = hloop_create_tcp_server(loop, host, port, on_accept);
if (listenio == NULL) {
exit(1);
}
hloop_run(loop);
return 0;
}
int main(int argc, char** argv) {
if (argc < 2) {
printf("Usage: cmd port\n");
return -10;
}
port = atoi(argv[1]);
worker_loops = (hloop_t**)malloc(sizeof(hloop_t*) * thread_num);
for (int i = 0; i < thread_num; ++i) {
worker_loops[i] = hloop_new(HLOOP_FLAG_AUTO_FREE);
hthread_create(worker_thread, worker_loops[i]);
}
accept_loop = hloop_new(HLOOP_FLAG_AUTO_FREE);
accept_thread(accept_loop);
return 0;
}
```
--------------------------------
### Setup SSL Upstream Forwarding (Macro)
Source: https://github.com/ithewei/libhv/blob/master/docs/cn/hloop.md
Macro to simplify setting up SSL TCP upstream forwarding. It's a convenience wrapper around hio_setup_tcp_upstream.
```c
#define hio_setup_ssl_upstream(io, host, port) hio_setup_tcp_upstream(io, host, port, 1)
```
--------------------------------
### Test protorpc Client: Add Operation
Source: https://github.com/ithewei/libhv/wiki/中文教程
Example of using the protorpc client to perform an 'add' operation, showing successful connection, login, and calculation.
```bash
$ bin/protorpc_client 127.0.0.1 1234 add 1 2
connected to 127.0.0.1:1234! connfd=4
id: 1
method: "login"
params: "\n\005admin\022\006123456"
login success!
user_id: 123456
token: "admin:123456"
id: 2
method: "add"
params: "\010\001"
params: "\010\002"
calc success!
1 add 2 = 3
disconnected to 127.0.0.1:1234! connfd=4
```
--------------------------------
### Build kcptun with libhv
Source: https://github.com/ithewei/libhv/blob/master/examples/kcptun/README.md
Compile kcptun with KCP support using the provided build script. Ensure you have the necessary build tools installed.
```shell
./configure --with-kcp
make clean
make examples
make kcptun
```
--------------------------------
### Run iperf and tcp_proxy_server for Bandwidth Test
Source: https://github.com/ithewei/libhv/blob/master/README.md
Set up an iperf server and a libhv tcp_proxy_server to measure bandwidth. Ensure iperf is installed and running in the background.
```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
```
--------------------------------
### C UDP Echo Server Example
Source: https://github.com/ithewei/libhv/wiki/中文教程
Sets up a UDP echo server in C using libhv. It binds to a specified port and echoes back any received data. Requires compilation with the hv library.
```c
#include "hv/hloop.h"
#include "hv/hsocket.h"
static void on_recvfrom(hio_t* io, void* buf, int readbytes) {
printf("on_recvfrom fd=%d readbytes=%d\n", hio_fd(io), readbytes);
char localaddrstr[SOCKADDR_STRLEN] = {0};
char peeraddrstr[SOCKADDR_STRLEN] = {0};
printf("[%s] <=> [%s]\n",
SOCKADDR_STR(hio_localaddr(io), localaddrstr),
SOCKADDR_STR(hio_peeraddr(io), peeraddrstr));
printf("< %.*s", readbytes, (char*)buf);
// 回显数据
printf("> %.*s", readbytes, (char*)buf);
hio_write(io, buf, readbytes);
}
int main(int argc, char** argv) {
if (argc < 2) {
printf("Usage: %s port\n", argv[0]);
return -10;
}
int port = atoi(argv[1]);
// 创建事件循环
hloop_t* loop = hloop_new(0);
// 创建UDP服务
hio_t* io = hloop_create_udp_server(loop, "0.0.0.0", port);
if (io == NULL) {
return -20;
}
// 设置read回调
hio_setcb_read(io, on_recvfrom);
// 开始读
hio_read(io);
// 运行事件循环
hloop_run(loop);
// 释放事件循环
hloop_free(&loop);
return 0;
}
```
--------------------------------
### Compile and Run HTTP Server (Shell)
Source: https://github.com/ithewei/libhv/wiki/中文教程
Shell commands to compile a C++ HTTP server example using g++ and libhv, and then run the compiled executable.
```shell
c++ -std=c++11 examples/http_server_test.cpp -o bin/http_server_test -lhv
bin/http_server_test
```
--------------------------------
### Configure libhv with OpenSSL support (Makefile)
Source: https://github.com/ithewei/libhv/wiki/FAQ
Use this command to enable SSL/TLS support when building libhv using Makefiles. Ensure OpenSSL is installed on your system.
```shell
./configure --with-openssl
make clean && make && sudo make install
```
--------------------------------
### Setup TCP Upstream Forwarding
Source: https://github.com/ithewei/libhv/blob/master/docs/cn/hloop.md
Establishes TCP forwarding to a specified host and port. Can optionally enable SSL. Returns the upstream I/O object.
```c
hio_t* hio_setup_tcp_upstream(hio_t* io, const char* host, int port, int ssl DEFAULT(0));
```
--------------------------------
### Simple Asynchronous HTTP Client in C++
Source: https://github.com/ithewei/libhv/wiki/中文教程
An asynchronous HTTP client example using libhv. This snippet demonstrates sending a POST request asynchronously and processing the response in a callback. It requires 'requests.h' and 'hthread.h'.
```cpp
#include "requests.h"
#include "hthread.h" // import hv_gettid
static void test_http_async_client(int* finished) {
printf("test_http_async_client request thread tid=%ld\n", hv_gettid());
HttpRequestPtr req(new HttpRequest);
req->method = HTTP_POST;
req->url = "127.0.0.1:8080/echo";
req->headers["Connection"] = "keep-alive";
req->body = "this is an async request.";
req->timeout = 10;
http_client_send_async(req, [finished](const HttpResponsePtr& resp) {
printf("test_http_async_client response thread tid=%ld\n", hv_gettid());
if (resp == NULL) {
printf("request failed!\n");
} else {
printf("%d %s\r\n", resp->status_code, resp->status_message());
printf("%s\n", resp->body.c_str());
}
*finished = 1;
});
}
int main() {
int finished = 0;
test_http_async_client(&finished);
// demo wait async ResponseCallback
while (!finished) {
hv_delay(100);
}
printf("finished!\n");
return 0;
}
```
--------------------------------
### Call API service with curl
Source: https://github.com/ithewei/libhv/blob/master/README-CN.md
Examples of calling various API endpoints using curl, including GET, POST, and query parameters.
```bash
bin/curl -v localhost:8080/ping
```
```bash
bin/curl -v localhost:8080/echo -d "hello,world!"
```
```bash
bin/curl -v localhost:8080/query?page_no=1\&page_size=10
```
```bash
bin/curl -v localhost:8080/kv -H "Content-Type:application/x-www-form-urlencoded" -d 'user=admin&pswd=123456'
```
```bash
bin/curl -v localhost:8080/json -H "Content-Type:application/json" -d '{"user":"admin","pswd":"123456"}'
```
```bash
bin/curl -v localhost:8080/form -F 'user=admin' -F 'pswd=123456'
```
```bash
bin/curl -v localhost:8080/upload -d "@LICENSE"
```
```bash
bin/curl -v localhost:8080/upload -F "file=@LICENSE"
```
```bash
bin/curl -v localhost:8080/test -H "Content-Type:application/x-www-form-urlencoded" -d 'bool=1&int=123&float=3.14&string=hello'
```
```bash
bin/curl -v localhost:8080/test -H "Content-Type:application/json" -d '{"bool":true,"int":123,"float":3.14,"string":"hello"}'
```
```bash
bin/curl -v localhost:8080/test -F 'bool=1' -F 'int=123' -F 'float=3.14' -F 'string=hello'
```
--------------------------------
### View configure help
Source: https://github.com/ithewei/libhv/blob/master/BUILD.md
Display all available configuration options for the ./configure script.
```bash
./configure --help
```
--------------------------------
### Create and Run Event Loop (C)
Source: https://github.com/ithewei/libhv/wiki/中文教程
Initializes a libhv event loop, adds a recurring timer callback, and starts the loop. The `hloop_new`, `htimer_add`, and `hloop_run` functions are key for event-driven programming.
```c
#include "hv/hloop.h"
// 定时器回调函数
static void on_timer(htimer_t* timer) {
printf("time=%lus\n", (unsigned long)time(NULL));
}
int main() {
// 新建一个事件循环结构体
hloop_t* loop = hloop_new(0);
// 添加一个定时器
htimer_add(loop, on_timer, 1000, INFINITE);
// 运行事件循环
hloop_run(loop);
// 释放事件循环结构体
hloop_free(&loop);
return 0;
}
```
--------------------------------
### Create a Simple WebSocket Server with libhv
Source: https://github.com/ithewei/libhv/wiki/中文教程
This C++ code demonstrates how to set up a basic WebSocket server using libhv. It includes callbacks for connection opening, message reception, and connection closing. The server sends the current time every second to connected clients. Compile with C++11 support and link against the hv library.
```cpp
#include "WebSocketServer.h"
#include "EventLoop.h"
#include "htime.h"
using namespace hv;
int main(int argc, char** argv) {
if (argc < 2) {
printf("Usage: %s port\n", argv[0]);
return -10;
}
int port = atoi(argv[1]);
WebSocketServerCallbacks ws;
ws.onopen = [](const WebSocketChannelPtr& channel, const std::string& url) {
printf("onopen: GET %s\n", url.c_str());
// send(time) every 1s
setInterval(1000, [channel](TimerID id) {
if (channel->isConnected()) {
char str[DATETIME_FMT_BUFLEN] = {0};
datetime_t dt = datetime_now();
datetime_fmt(&dt, str);
channel->send(str);
} else {
killTimer(id);
}
});
};
ws.onmessage = [](const WebSocketChannelPtr& channel, const std::string& msg) {
printf("onmessage: %s\n", msg.c_str());
};
ws.onclose = [](const WebSocketChannelPtr& channel) {
printf("onclose\n");
};
websocket_server_t server;
server.port = port;
server.ws = &ws;
websocket_server_run(&server);
return 0;
}
```
```shell
c++ -std=c++11 examples/websocket_server_test.cpp -o bin/websocket_server_test -I/usr/local/include/hv -lhv
bin/websocket_server_test 8888
```
--------------------------------
### vcpkg installation
Source: https://github.com/ithewei/libhv/wiki/中文教程
Installs libhv using the vcpkg package manager. Note that the vcpkg version might not be the latest.
```bash
vcpkg install libhv
```
--------------------------------
### Initialize SSL Context with Certificates
Source: https://github.com/ithewei/libhv/wiki/中文FAQ
This C code demonstrates how to initialize an SSL context for HTTPS by providing certificate and key file paths. Ensure the certificate files exist and are valid.
```c
typedef struct {
const char* crt_file;
const char* key_file;
const char* ca_file;
const char* ca_path;
short verify_peer;
short endpoint;
} hssl_ctx_init_param_t;
HV_EXPORT hssl_ctx_t hssl_ctx_init(hssl_ctx_init_param_t* param);
hssl_ctx_init_param_t param;
memset(¶m, 0, sizeof(param));
param.crt_file = "cert/server.crt";
param.key_file = "cert/server.key";
if (hssl_ctx_init(¶m) == NULL) {
fprintf(stderr, "hssl_ctx_init failed!\n");
return -20;
}
```
--------------------------------
### HttpRequest: Method and URL
Source: https://github.com/ithewei/libhv/blob/master/docs/cn/HttpMessage.md
Set and get the HTTP method using SetMethod/Method. Set, get, and parse the URL using SetUrl/Url/ParseUrl. Host and Path can also be extracted from the URL.
```c++
void SetMethod(const char* method);
const char* Method();
void SetUrl(const char* url);
const std::string& Url();
void ParseUrl();
std::string Host();
std::string Path();
```
--------------------------------
### HttpMessage: Generic Data Setting and Getting
Source: https://github.com/ithewei/libhv/blob/master/docs/cn/HttpMessage.md
The generic Set() method populates data based on Content-Type. Get(), GetString(), GetBool(), GetInt(), and GetFloat() retrieve data, performing type conversions as needed.
```c++
template
void Set(const char* key, const T& value);
template
T Get(const char* key, T defvalue = 0);
std::string GetString(const char* key, const std::string& = "");
bool GetBool(const char* key, bool defvalue = 0);
int64_t GetInt(const char* key, int64_t defvalue = 0);
double GetFloat(const char* key, double defvalue = 0);
```
--------------------------------
### kcptun Server Help
Source: https://github.com/ithewei/libhv/blob/master/examples/kcptun/README.md
Displays the available command-line options for the kcptun server. Use this to configure listening address, target server, and transmission mode.
```shell
$ bin/kcptun_server -h
```
--------------------------------
### Callback Management
Source: https://github.com/ithewei/libhv/blob/master/docs/cn/hloop.md
Functions for setting and getting IO event callbacks.
```APIDOC
## Callback Management
### Setting Callbacks
- **`hio_setcb_accept`**: Sets the callback for accept events.
- **`hio_setcb_connect`**: Sets the callback for connect events.
- **`hio_setcb_read`**: Sets the callback for read events.
- **`hio_setcb_write`**: Sets the callback for write events.
- **`hio_setcb_close`**: Sets the callback for close events.
### Getting Callbacks
- **`hio_getcb_accept`**: Gets the current accept callback.
- **`hio_getcb_connect`**: Gets the current connect callback.
- **`hio_getcb_read`**: Gets the current read callback.
- **`hio_getcb_write`**: Gets the current write callback.
- **`hio_getcb_close`**: Gets the current close callback.
**Note**: The specific callback function types (e.g., `haccept_cb`, `hconnect_cb`) are defined elsewhere in the library.
```
--------------------------------
### Error Handling
Source: https://github.com/ithewei/libhv/blob/master/docs/API.md
Provides a function to get error messages from error codes.
```APIDOC
## herr.h
### Description
Error handling utilities.
### Functions
- hv_strerror: Get a string description of an error code.
```
--------------------------------
### Accept Connections
Source: https://github.com/ithewei/libhv/blob/master/docs/cn/hloop.md
Initiate the process of accepting incoming network connections.
```c
// 接收连接
// hio_add(io, HV_READ) => accept => haccept_cb
int hio_accept (hio_t* io);
```
--------------------------------
### Get IO Event Callbacks
Source: https://github.com/ithewei/libhv/blob/master/docs/cn/hloop.md
Retrieve the currently registered callback functions for IO events.
```c
// 获取accept回调
haccept_cb hio_getcb_accept(hio_t* io);
// 获取连接回调
hconnect_cb hio_getcb_connect(hio_t* io);
// 获取读回调
hread_cb hio_getcb_read(hio_t* io);
// 获取写回调
hwrite_cb hio_getcb_write(hio_t* io);
// 获取关闭回调
hclose_cb hio_getcb_close(hio_t* io);
```
--------------------------------
### Create a Simple WebSocket Client with libhv
Source: https://github.com/ithewei/libhv/wiki/中文教程
This C++ code demonstrates how to create a WebSocket client using libhv. It connects to a specified URL, sends 'hello' upon connection, logs received messages, and handles connection closure. It also configures automatic reconnection with a delay policy. Compile with C++11 support and link against the hv library.
```cpp
#include "WebSocketClient.h"
using namespace hv;
int main(int argc, char** argv) {
if (argc < 2) {
printf("Usage: %s url\n", argv[0]);
return -10;
}
const char* url = argv[1];
WebSocketClient ws;
ws.onopen = [&ws]() {
printf("onopen\n");
ws.send("hello");
};
ws.onclose = []() {
printf("onclose\n");
};
ws.onmessage = [](const std::string& msg) {
printf("onmessage: %s\n", msg.c_str());
};
// reconnect: 1,2,4,8,10,10,10...
ReconnectInfo reconn;
reconn.min_delay = 1000;
reconn.max_delay = 10000;
reconn.delay_policy = 2;
ws.setReconnect(&reconn);
ws.open(url);
while (1) hv_delay(1000);
return 0;
}
```
```shell
c++ -std=c++11 examples/websocket_client_test.cpp -o bin/websocket_client_test -I/usr/local/include/hv -lhv
bin/websocket_client_test ws://127.0.0.1:8888/
```
--------------------------------
### Get Last IO Times
Source: https://github.com/ithewei/libhv/blob/master/docs/cn/hloop.md
Retrieve the timestamps (in milliseconds) of the last read and write operations.
```c
// 获取最后读的时间
uint64_t hio_last_read_time(hio_t* io); // ms
// 获取最后写的时间
uint64_t hio_last_write_time(hio_t* io); // ms
```
--------------------------------
### Build and Test protorpc with libhv
Source: https://github.com/ithewei/libhv/wiki/中文教程
Steps to clone the libhv repository, build the protorpc component, and test its server and client functionalities with various operations.
```bash
git clone https://github.com/ithewei/libhv
cd libhv
make protorpc
bin/protorpc_server 1234
bin/protorpc_client 127.0.0.1 1234 add 1 2
bin/protorpc_client 127.0.0.1 1234 div 1 0
bin/protorpc_client 127.0.0.1 1234 xyz 1 2
```
--------------------------------
### Test HTTP Query API
Source: https://github.com/ithewei/libhv/blob/master/README.md
Send a GET request with query parameters to the /query API endpoint.
```shell
bin/curl -v localhost:8080/query?page_no=1&page_size=10
```
--------------------------------
### Set and Get IO Context
Source: https://github.com/ithewei/libhv/blob/master/docs/cn/hloop.md
Manage the context associated with an IO object. The context can be any user-defined data.
```c
void hio_set_context(hio_t* io, void* ctx);
void* hio_context(hio_t* io);
```
--------------------------------
### Read Data
Source: https://github.com/ithewei/libhv/blob/master/docs/cn/hloop.md
Start or stop reading data from an IO object. This function can be used to initiate a read operation.
```c
// 读
// hio_add(io, HV_READ) => read => hread_cb
int hio_read (hio_t* io);
// 开始读
#define hio_read_start(io) hio_read(io)
// 停止读
#define hio_read_stop(io) hio_del(io, HV_READ)
```