initial commit
This commit is contained in:
656
third_party/libhv/docs/API.md
vendored
Executable file
656
third_party/libhv/docs/API.md
vendored
Executable file
@@ -0,0 +1,656 @@
|
||||
# libhv API Manual
|
||||
|
||||
## base
|
||||
|
||||
### hplatform.h
|
||||
- OS: OS_WIN, OS_UNIX (OS_LINUX, OS_ANDROID, OS_DARWIN ...)
|
||||
- ARCH: ARCH_X86, ARCH_X64, ARCH_ARM, ARCH_ARM64
|
||||
- COMPILER: COMPILER_MSVC, COMPILER_MINGW, COMPILER_GCC, COMPILER_CLANG
|
||||
- BYTE_ORDER: BIG_ENDIAN, LITTLE_ENDIAN
|
||||
- stdbool.h: bool, true, false
|
||||
- stdint.h: int8_t, int16_t, int32_t, int64_t
|
||||
- hv_sleep, hv_msleep, hv_usleep, hv_delay
|
||||
- hv_mkdir
|
||||
- stricmp, strcasecmp
|
||||
|
||||
### hexport.h
|
||||
- HV_EXPORT, HV_INLINE
|
||||
- HV_SOURCE, HV_STATICLIB, HV_DYNAMICLIB
|
||||
- HV_DEPRECATED
|
||||
- HV_UNUSED
|
||||
- EXTERN_C, BEGIN_EXTERN_C, END_EXTERN_C
|
||||
- BEGIN_NAMESPACE, END_NAMESPACE, USING_NAMESPACE
|
||||
- DEFAULT
|
||||
- ENUM, STRUCT
|
||||
- IN, OUT, INOUT
|
||||
- OPTIONAL, REQUIRED, REPEATED
|
||||
|
||||
### hdef.h
|
||||
- ABS, NABS
|
||||
- ARRAY_SIZE
|
||||
- BITSET, BITCLR, BITGET
|
||||
- CR, LF, CRLF
|
||||
- FLOAT_EQUAL_ZERO
|
||||
- INFINITE
|
||||
- IS_ALPHA, IS_DIGIT, IS_ALPHANUM
|
||||
- IS_CNTRL, IS_GRAPH
|
||||
- IS_HEX
|
||||
- IS_LOWER, IS_UPPER
|
||||
- LOWER, UPPER
|
||||
- MAKEWORD, LOBYTE, HIBYTE
|
||||
- MAKELONG, LOWORD, HIWORD
|
||||
- MAKEINT64, LOINT, HIINT
|
||||
- MAKE_FOURCC
|
||||
- MAX, MIN, LIMIT
|
||||
- MAX_PATH
|
||||
- NULL, TRUE, FALSE
|
||||
- SAFE_FREE, SAFE_DELETE, SAFE_DELETE_ARRAY, SAFE_RELEASE
|
||||
- STRINGCAT
|
||||
- STRINGIFY
|
||||
- offsetof, offsetofend
|
||||
- container_of
|
||||
- prefetch
|
||||
- printd, printe
|
||||
|
||||
### hatomic.h
|
||||
- hatomic_flag_t, hatomic_t
|
||||
- hatomic_flag_test_and_set
|
||||
- hatomic_flag_clear
|
||||
- hatomic_add
|
||||
- hatomic_sub
|
||||
- hatomic_inc
|
||||
- hatomic_dec
|
||||
|
||||
### herr.h
|
||||
- hv_strerror
|
||||
|
||||
### htime.h
|
||||
- IS_LEAP_YEAR
|
||||
- datetime_t
|
||||
- gettick_ms
|
||||
- gettimeofday
|
||||
- gettimeofday_ms
|
||||
- gettimeofday_us
|
||||
- gethrtime_us
|
||||
- datetime_now
|
||||
- datetime_localtime
|
||||
- datetime_mktime
|
||||
- datetime_past
|
||||
- datetime_future
|
||||
- duration_fmt
|
||||
- datetime_fmt
|
||||
- gmtime_fmt
|
||||
- days_of_month
|
||||
- month_atoi
|
||||
- month_itoa
|
||||
- weekday_atoi
|
||||
- weekday_itoa
|
||||
- hv_compile_datetime
|
||||
- cron_next_timeout
|
||||
|
||||
### hmath.h
|
||||
- floor2e
|
||||
- ceil2e
|
||||
- varint_encode
|
||||
- varint_decode
|
||||
|
||||
### hbase.h
|
||||
- hv_malloc
|
||||
- hv_calloc
|
||||
- hv_realloc
|
||||
- hv_zalloc
|
||||
- hv_strncpy
|
||||
- hv_strncat
|
||||
- hv_strlower
|
||||
- hv_strupper
|
||||
- hv_strreverse
|
||||
- hv_strstartswith
|
||||
- hv_strendswith
|
||||
- hv_strcontains
|
||||
- hv_wildcard_match
|
||||
- hv_strnchr
|
||||
- hv_strrchr_dot
|
||||
- hv_strrchr_dir
|
||||
- hv_basename
|
||||
- hv_suffixname
|
||||
- hv_mkdir_p
|
||||
- hv_rmdir_p
|
||||
- hv_exists
|
||||
- hv_isdir
|
||||
- hv_isfile
|
||||
- hv_islink
|
||||
- hv_filesize
|
||||
- get_executable_path
|
||||
- get_executable_dir
|
||||
- get_executable_file
|
||||
- get_run_dir
|
||||
- hv_rand
|
||||
- hv_random_string
|
||||
- hv_getboolean
|
||||
- hv_parse_size
|
||||
- hv_parse_time
|
||||
- hv_parse_url
|
||||
|
||||
### hversion.h
|
||||
- hv_version
|
||||
- hv_compile_version
|
||||
- version_atoi
|
||||
- version_itoa
|
||||
|
||||
### hsysinfo.h
|
||||
- get_ncpu
|
||||
- get_meminfo
|
||||
|
||||
### hproc.h
|
||||
- hproc_spawn
|
||||
|
||||
### hthread.h
|
||||
- hv_getpid
|
||||
- hv_gettid
|
||||
- HTHREAD_RETTYPE
|
||||
- HTHREAD_ROUTINE
|
||||
- hthread_create
|
||||
- hthread_join
|
||||
- class HThread
|
||||
|
||||
### hmutex.h
|
||||
- hmutex_t
|
||||
- hmutex_init
|
||||
- hmutex_destroy
|
||||
- hmutex_lock
|
||||
- hmutex_unlock
|
||||
- hspinlock_t
|
||||
- hspinlock_init
|
||||
- hspinlock_destroy
|
||||
- hspinlock_lock
|
||||
- hspinlock_unlock
|
||||
- hrwlock_t
|
||||
- hrwlock_init
|
||||
- hrwlock_destroy
|
||||
- hrwlock_rdlock
|
||||
- hrwlock_rdunlock
|
||||
- hrwlock_wrlock
|
||||
- hrwlock_wrunlock
|
||||
- htimed_mutex_t
|
||||
- htimed_mutex_init
|
||||
- htimed_mutex_destroy
|
||||
- htimed_mutex_lock
|
||||
- htimed_mutex_lock_for
|
||||
- htimed_mutex_unlock
|
||||
- hcondvar_t
|
||||
- hcondvar_init
|
||||
- hcondvar_destroy
|
||||
- hcondvar_wait
|
||||
- hcondvar_wait_for
|
||||
- hcondvar_signal
|
||||
- hcondvar_broadcast
|
||||
- hsem_init
|
||||
- hsem_destroy
|
||||
- hsem_wait
|
||||
- hsem_post
|
||||
- hsem_timedwait
|
||||
- honce_t
|
||||
- HONCE_INIT
|
||||
- honce
|
||||
- class `hv::MutexLock`
|
||||
- class `hv::SpinLock`
|
||||
- class `hv::RWLock`
|
||||
- class `hv::LockGuard`
|
||||
- synchronized
|
||||
|
||||
### hsocket.h
|
||||
- INVALID_SOCKET
|
||||
- closesocket
|
||||
- blocking
|
||||
- nonblocking
|
||||
- Bind
|
||||
- Listen
|
||||
- Connect
|
||||
- ConnectNonblock
|
||||
- ConnectTimeout
|
||||
- ResolveAddr
|
||||
- Socketpair
|
||||
- socket_errno
|
||||
- socket_strerror
|
||||
- sockaddr_u
|
||||
- sockaddr_ip
|
||||
- sockaddr_port
|
||||
- sockaddr_set_ip
|
||||
- sockaddr_set_port
|
||||
- sockaddr_set_ipport
|
||||
- sockaddr_len
|
||||
- sockaddr_str
|
||||
- sockaddr_print
|
||||
- SOCKADDR_LEN
|
||||
- SOCKADDR_STR
|
||||
- SOCKADDR_PRINT
|
||||
- tcp_nodelay
|
||||
- tcp_nopush
|
||||
- tcp_keepalive
|
||||
- udp_broadcast
|
||||
- ip_v6only
|
||||
- so_sndtimeo
|
||||
- so_rcvtimeo
|
||||
- so_sndbuf
|
||||
- so_rcvbuf
|
||||
- so_reuseaddr
|
||||
- so_reuseport
|
||||
- so_linger
|
||||
|
||||
### hlog.h
|
||||
- default_logger
|
||||
- file_logger
|
||||
- stderr_logger
|
||||
- stdout_logger
|
||||
- logger_create
|
||||
- logger_destroy
|
||||
- logger_enable_color
|
||||
- logger_enable_fsync
|
||||
- logger_fsync
|
||||
- logger_print
|
||||
- logger_set_file
|
||||
- logger_set_handler
|
||||
- logger_set_level
|
||||
- logger_set_max_bufsize
|
||||
- logger_set_max_filesize
|
||||
- logger_set_remain_days
|
||||
- logger_get_cur_file
|
||||
- hlogd, hlogi, hlogw, hloge, hlogf
|
||||
- LOGD, LOGI, LOGW, LOGE, LOGF
|
||||
|
||||
### hbuf.h
|
||||
- hbuf_t
|
||||
- offset_buf_t
|
||||
- class HBuf
|
||||
- class HVLBuf
|
||||
- class HRingBuf
|
||||
|
||||
### hmain.h
|
||||
- main_ctx_init
|
||||
- parse_opt
|
||||
- parse_opt_long
|
||||
- dump_opt_long
|
||||
- get_arg
|
||||
- get_env
|
||||
- setproctitle
|
||||
- signal_init
|
||||
- signal_handle
|
||||
- create_pidfile
|
||||
- delete_pidfile
|
||||
- getpid_form_pidfile
|
||||
- master_workers_run
|
||||
|
||||
### hstring.h
|
||||
- to_string
|
||||
- from_string
|
||||
- toupper
|
||||
- tolower
|
||||
- reverse
|
||||
- startswith
|
||||
- endswith
|
||||
- contains
|
||||
- asprintf
|
||||
- trim
|
||||
- ltrim
|
||||
- rtrim
|
||||
- trim_pairs
|
||||
- split
|
||||
- splitKV
|
||||
- replace
|
||||
- replaceAll
|
||||
|
||||
### hfile.h
|
||||
- class HFile
|
||||
|
||||
### hpath.h
|
||||
- exists
|
||||
- isdir
|
||||
- isfile
|
||||
- islink
|
||||
- basename
|
||||
- dirname
|
||||
- filename
|
||||
- suffixname
|
||||
- join
|
||||
|
||||
### hdir.h
|
||||
- listdir
|
||||
|
||||
### hurl.h
|
||||
- HUrl::escape
|
||||
- HUrl::unescape
|
||||
- HUrl::parse
|
||||
- HUrl::dump
|
||||
|
||||
### hscope.h
|
||||
- defer
|
||||
- template ScopeCleanup
|
||||
- template ScopeFree
|
||||
- template ScopeDelete
|
||||
- template ScopeDeleteArray
|
||||
- template ScopeRelease
|
||||
- template ScopeLock
|
||||
|
||||
### ifconfig.h
|
||||
- ifconfig
|
||||
|
||||
## utils
|
||||
### md5.h
|
||||
- HV_MD5Init
|
||||
- HV_MD5Update
|
||||
- HV_MD5Final
|
||||
- hv_md5
|
||||
- hv_md5_hex
|
||||
|
||||
### sha1.h
|
||||
- HV_SHA1Init
|
||||
- HV_SHA1Update
|
||||
- HV_SHA1Final
|
||||
- HV_SHA1
|
||||
- hv_sha1
|
||||
- hv_sha1_hex
|
||||
|
||||
### base64.h
|
||||
- hv_base64_decode
|
||||
- hv_base64_encode
|
||||
|
||||
### json.hpp
|
||||
- json::parse
|
||||
- json::dump
|
||||
|
||||
### singleton.h
|
||||
- DISABLE_COPY
|
||||
- SINGLETON_DECL
|
||||
- SINGLETON_IMPL
|
||||
|
||||
## event
|
||||
|
||||
### hloop.h
|
||||
- hloop_create_tcp_client
|
||||
- hloop_create_tcp_server
|
||||
- hloop_create_udp_client
|
||||
- hloop_create_udp_server
|
||||
- hloop_create_ssl_client
|
||||
- hloop_create_ssl_server
|
||||
- hloop_new
|
||||
- hloop_free
|
||||
- hloop_run
|
||||
- hloop_stop
|
||||
- hloop_pause
|
||||
- hloop_resume
|
||||
- hloop_status
|
||||
- hloop_pid
|
||||
- hloop_tid
|
||||
- hloop_now
|
||||
- hloop_now_ms
|
||||
- hloop_now_us
|
||||
- hloop_update_time
|
||||
- hloop_set_userdata
|
||||
- hloop_userdata
|
||||
- hloop_wakeup
|
||||
- hloop_post_event
|
||||
- hevent_loop
|
||||
- hevent_type
|
||||
- hevent_id
|
||||
- hevent_priority
|
||||
- hevent_userdata
|
||||
- hevent_set_priority
|
||||
- hevent_ser_userdata
|
||||
- haccept
|
||||
- hconnect
|
||||
- hread
|
||||
- hwrite
|
||||
- hrecv
|
||||
- hsend
|
||||
- hrecvfrom
|
||||
- hsendto
|
||||
- hio_add
|
||||
- hio_del
|
||||
- hio_get
|
||||
- hio_detach
|
||||
- hio_attach
|
||||
- hio_read
|
||||
- hio_read_start
|
||||
- hio_read_stop
|
||||
- hio_read_once
|
||||
- hio_read_until
|
||||
- hio_read_until_length
|
||||
- hio_read_until_delim
|
||||
- hio_read_readline
|
||||
- hio_read_readstring
|
||||
- hio_read_readbytes
|
||||
- hio_write
|
||||
- hio_close
|
||||
- hio_accept
|
||||
- hio_connect
|
||||
- hio_fd
|
||||
- hio_id
|
||||
- hio_type
|
||||
- hio_error
|
||||
- hio_localaddr
|
||||
- hio_peeraddr
|
||||
- hio_events
|
||||
- hio_revents
|
||||
- hio_is_opened
|
||||
- hio_is_closed
|
||||
- hio_enable_ssl
|
||||
- hio_is_ssl
|
||||
- hio_get_ssl
|
||||
- hio_set_ssl
|
||||
- hio_get_ssl_ctx
|
||||
- hio_set_ssl_ctx
|
||||
- hio_new_ssl_ctx
|
||||
- hio_setcb_accept
|
||||
- hio_setcb_connect
|
||||
- hio_setcb_read
|
||||
- hio_setcb_write
|
||||
- hio_setcb_close
|
||||
- hio_getcb_accept
|
||||
- hio_getcb_connect
|
||||
- hio_getcb_read
|
||||
- hio_getcb_write
|
||||
- hio_getcb_close
|
||||
- hio_set_type
|
||||
- hio_set_localaddr
|
||||
- hio_set_peeraddr
|
||||
- hio_set_readbuf
|
||||
- hio_set_connect_timeout
|
||||
- hio_set_close_timeout
|
||||
- hio_set_read_timeout
|
||||
- hio_set_write_timeout
|
||||
- hio_set_keepalive_timeout
|
||||
- hio_set_heartbeat
|
||||
- hio_set_unpack
|
||||
- hio_unset_unpack
|
||||
- hio_read_upstream
|
||||
- hio_write_upstream
|
||||
- hio_close_upstream
|
||||
- hio_setup_upstream
|
||||
- hio_get_upstream
|
||||
- hio_setup_tcp_upstream
|
||||
- hio_setup_ssl_upstream
|
||||
- hio_setup_udp_upstream
|
||||
- hio_create_socket
|
||||
- hio_create_pipe
|
||||
- hio_context
|
||||
- hio_set_context
|
||||
- htimer_add
|
||||
- htimer_add_period
|
||||
- htimer_del
|
||||
- htimer_reset
|
||||
- hidle_add
|
||||
- hidle_del
|
||||
- hsignal_add
|
||||
- hsignal_del
|
||||
|
||||
### nlog.h
|
||||
- network_logger
|
||||
- nlog_listen
|
||||
|
||||
## evpp
|
||||
- class Buffer
|
||||
- class Channel
|
||||
- class Event
|
||||
- class EventLoop
|
||||
- class EventLoopThread
|
||||
- class EventLoopThreadPool
|
||||
- class TcpClient
|
||||
- class TcpServer
|
||||
- class UdpClient
|
||||
- class UdpServer
|
||||
|
||||
## ssl
|
||||
- hssl_ctx_init
|
||||
- hssl_ctx_cleanup
|
||||
- hssl_ctx_instance
|
||||
- hssl_ctx_new
|
||||
- hssl_ctx_free
|
||||
- hssl_new
|
||||
- hssl_free
|
||||
- hssl_accept
|
||||
- hssl_connnect
|
||||
- hssl_read
|
||||
- hssl_write
|
||||
- hssl_close
|
||||
- hssl_set_sni_hostname
|
||||
|
||||
## protocol
|
||||
|
||||
### dns.h
|
||||
- dns_name_decode
|
||||
- dns_name_encode
|
||||
- dns_pack
|
||||
- dns_unpack
|
||||
- dns_rr_pack
|
||||
- dns_rr_unpack
|
||||
- dns_query
|
||||
- dns_free
|
||||
- nslookup
|
||||
|
||||
### ftp.h
|
||||
- ftp_command_str
|
||||
- ftp_connect
|
||||
- ftp_login
|
||||
- ftp_exec
|
||||
- ftp_upload
|
||||
- ftp_download
|
||||
- ftp_download_with_cb
|
||||
- ftp_quit
|
||||
- ftp_status_str
|
||||
|
||||
### smtp.h
|
||||
- smtp_command_str
|
||||
- smtp_status_str
|
||||
- smtp_build_command
|
||||
- sendmail
|
||||
|
||||
### icmp.h
|
||||
- ping
|
||||
|
||||
## http
|
||||
- class HttpMessage
|
||||
- class HttpRequest
|
||||
- class HttpResponse
|
||||
- class HttpParser
|
||||
|
||||
### httpdef.h
|
||||
- http_content_type_enum
|
||||
- http_content_type_enum_by_suffix
|
||||
- http_content_type_str
|
||||
- http_content_type_str_by_suffix
|
||||
- http_content_type_suffix
|
||||
- http_errno_description
|
||||
- http_errno_name
|
||||
- http_method_enum
|
||||
- http_method_str
|
||||
- http_status_enum
|
||||
- http_status_str
|
||||
|
||||
### http_content.h
|
||||
- parse_query_params
|
||||
- parse_json
|
||||
- parse_multipart
|
||||
- dump_query_params
|
||||
- dump_json
|
||||
- dump_multipart
|
||||
|
||||
### HttpClient.h
|
||||
- http_client_new
|
||||
- http_client_del
|
||||
- http_client_send
|
||||
- http_client_send_async
|
||||
- http_client_strerror
|
||||
- http_client_set_timeout
|
||||
- http_client_set_header
|
||||
- http_client_del_header
|
||||
- http_client_get_header
|
||||
- http_client_clear_headers
|
||||
- http_client_set_http_proxy
|
||||
- http_client_set_https_proxy
|
||||
- http_client_add_no_proxy
|
||||
- class HttpClient
|
||||
|
||||
### requests.h
|
||||
- requests::request
|
||||
- requests::get
|
||||
- requests::post
|
||||
- requests::put
|
||||
- requests::patch
|
||||
- requests::Delete
|
||||
- requests::head
|
||||
- requests::async
|
||||
|
||||
### axios.h
|
||||
- axios::axios
|
||||
- axios::get
|
||||
- axios::post
|
||||
- axios::put
|
||||
- axios::patch
|
||||
- axios::Delete
|
||||
- axios::head
|
||||
- axios::async
|
||||
|
||||
### HttpServer.h
|
||||
- http_server_run
|
||||
- http_server_stop
|
||||
- class HttpService
|
||||
- class HttpServer
|
||||
|
||||
### WebSocketClient.h
|
||||
- class WebSocketClient
|
||||
|
||||
### WebSocketServer.h
|
||||
- websocket_server_run
|
||||
- websocket_server_stop
|
||||
- class WebSocketService
|
||||
- class WebSocketServer
|
||||
|
||||
## mqtt
|
||||
- mqtt_client_new
|
||||
- mqtt_client_free
|
||||
- mqtt_client_run
|
||||
- mqtt_client_stop
|
||||
- mqtt_client_set_id
|
||||
- mqtt_client_set_will
|
||||
- mqtt_client_set_auth
|
||||
- mqtt_client_set_callback
|
||||
- mqtt_client_set_userdata
|
||||
- mqtt_client_get_userdata
|
||||
- mqtt_client_get_last_error
|
||||
- mqtt_client_set_ssl_ctx
|
||||
- mqtt_client_new_ssl_ctx
|
||||
- mqtt_client_set_reconnect
|
||||
- mqtt_client_reconnect
|
||||
- mqtt_client_set_connect_timeout
|
||||
- mqtt_client_connect
|
||||
- mqtt_client_is_connected
|
||||
- mqtt_client_disconnect
|
||||
- mqtt_client_publish
|
||||
- mqtt_client_subscribe
|
||||
- mqtt_client_unsubscribe
|
||||
- class MqttClient
|
||||
|
||||
## other
|
||||
- class HThreadPool
|
||||
- class HObjectPool
|
||||
- class ThreadLocalStorage
|
||||
31
third_party/libhv/docs/PLAN.md
vendored
Executable file
31
third_party/libhv/docs/PLAN.md
vendored
Executable file
@@ -0,0 +1,31 @@
|
||||
## Done
|
||||
|
||||
- base: cross platfrom infrastructure
|
||||
- event: select/poll/epoll/wepoll/kqueue/port
|
||||
- ssl: openssl/gnutls/mbedtls/wintls/appletls
|
||||
- rudp: KCP
|
||||
- evpp: c++ EventLoop interface similar to muduo and evpp
|
||||
- http client/server: include https http1/x http2
|
||||
- websocket client/server
|
||||
- mqtt client
|
||||
|
||||
## Improving
|
||||
|
||||
- Path router: optimized matching via trie?
|
||||
- FileCache use LRUCache
|
||||
|
||||
## Plan
|
||||
|
||||
- redis client
|
||||
- async DNS
|
||||
- lua binding
|
||||
- js binding
|
||||
- hrpc = libhv + protobuf
|
||||
- rudp: FEC, ARQ, UDT, QUIC
|
||||
- kcptun
|
||||
- have a taste of io_uring
|
||||
- coroutine
|
||||
- cppsocket.io
|
||||
- IM-libhv
|
||||
- MediaServer-libhv
|
||||
- GameServer-libhv
|
||||
153
third_party/libhv/docs/cn/Channel.md
vendored
Executable file
153
third_party/libhv/docs/cn/Channel.md
vendored
Executable file
@@ -0,0 +1,153 @@
|
||||
通道类
|
||||
|
||||
```c++
|
||||
|
||||
class Channel {
|
||||
|
||||
// 返回底层的io结构体指针
|
||||
hio_t* io() { return io_; }
|
||||
|
||||
// 返回socket文件描述符
|
||||
int fd() { return fd_; }
|
||||
|
||||
// 返回一个唯一标示id
|
||||
uint32_t id() { return id_; }
|
||||
|
||||
// 返回错误码
|
||||
int error() { return hio_error(io_); }
|
||||
|
||||
// 获取/设置/新建/删除 上下文
|
||||
void* context();
|
||||
void setContext(void* ctx);
|
||||
template<class T> T* newContext();
|
||||
template<class T> T* getContext();
|
||||
template<class T> void deleteContext();
|
||||
|
||||
// 获取/设置/新建/删除 上下文智能指针
|
||||
std::shared_ptr<void> contextPtr();
|
||||
void setContextPtr(const std::shared_ptr<void>& ctx);
|
||||
void setContextPtr(std::shared_ptr<void>&& ctx);
|
||||
template<class T> std::shared_ptr<T> newContextPtr();
|
||||
template<class T> std::shared_ptr<T> getContextPtr();
|
||||
void deleteContextPtr();
|
||||
|
||||
// 是否打开状态
|
||||
bool isOpened();
|
||||
|
||||
// 是否关闭状态
|
||||
bool isClosed();
|
||||
|
||||
// 开始读
|
||||
int startRead();
|
||||
|
||||
// 停止读
|
||||
int stopRead();
|
||||
|
||||
// 读一次
|
||||
int readOnce();
|
||||
// 读一个字符串
|
||||
int readString();
|
||||
// 读一行
|
||||
int readLine();
|
||||
// 读取N个字节
|
||||
int readBytes(int len);
|
||||
|
||||
// 写
|
||||
int write(const void* data, int size);
|
||||
int write(Buffer* buf);
|
||||
int write(const std::string& str);
|
||||
|
||||
// 设置最大读缓存
|
||||
void setMaxReadBufsize(uint32_t size);
|
||||
// 设置最大写缓存
|
||||
void setMaxWriteBufsize(uint32_t size);
|
||||
// 获取当前写缓存大小
|
||||
size_t writeBufsize();
|
||||
// 是否写完成
|
||||
bool isWriteComplete();
|
||||
|
||||
// 关闭
|
||||
int close(bool async = false);
|
||||
|
||||
// 读回调
|
||||
std::function<void(Buffer*)> onread;
|
||||
// 写回调
|
||||
std::function<void(Buffer*)> onwrite;
|
||||
// 关闭回调
|
||||
std::function<void()> onclose;
|
||||
};
|
||||
|
||||
// SocketChannel 继承自 Channel
|
||||
class SocketChannel : public Channel {
|
||||
// 连接状态回调
|
||||
std::function<void()> onconnect;
|
||||
// 心跳回调
|
||||
std::function<void()> heartbeat;
|
||||
|
||||
// 启用SSL/TLS加密通信
|
||||
int enableSSL();
|
||||
// 是否是SSL/TLS加密通信
|
||||
bool isSSL();
|
||||
// 设置SSL
|
||||
int setSSL(hssl_t ssl);
|
||||
// 设置SSL_CTX
|
||||
int setSslCtx(hssl_ctx_t ssl_ctx);
|
||||
// 新建SSL_CTX
|
||||
int newSslCtx(hssl_ctx_opt_t* opt);
|
||||
// 设置主机名
|
||||
int setHostname(const std::string& hostname);
|
||||
|
||||
// 设置连接超时
|
||||
void setConnectTimeout(int timeout_ms);
|
||||
|
||||
// 设置关闭超时 (说明:非阻塞写队列非空时,需要等待写完成再关闭)
|
||||
void setCloseTimeout(int timeout_ms);
|
||||
|
||||
// 设置读超时 (一段时间没有数据到来便自动关闭连接)
|
||||
void setReadTimeout(int timeout_ms);
|
||||
|
||||
// 设置写超时 (一段时间没有数据发送便自动关闭连接)
|
||||
void setWriteTimeout(int timeout_ms);
|
||||
|
||||
// 设置keepalive超时 (一段时间没有数据收发便自动关闭连接)
|
||||
void setKeepaliveTimeout(int timeout_ms);
|
||||
|
||||
// 设置心跳 (定时发送心跳包)
|
||||
void setHeartbeat(int interval_ms, std::function<void()> fn);
|
||||
|
||||
// 设置拆包规则
|
||||
void setUnpack(unpack_setting_t* setting);
|
||||
|
||||
// 开始连接
|
||||
int startConnect(int port, const char* host = "127.0.0.1");
|
||||
int startConnect(struct sockaddr* peeraddr);
|
||||
int startConnect();
|
||||
|
||||
// 是否已连接
|
||||
bool isConnected();
|
||||
|
||||
// 返回本地地址
|
||||
std::string localaddr();
|
||||
|
||||
// 返回对端地址
|
||||
std::string peeraddr();
|
||||
};
|
||||
|
||||
// WebSocketChannel 继承自 SocketChannel
|
||||
class WebSocketChannel : public SocketChannel {
|
||||
|
||||
// 发送文本帧
|
||||
int send(const std::string& msg, enum ws_opcode opcode = WS_OPCODE_TEXT, bool fin = true);
|
||||
|
||||
// 发送二进制帧
|
||||
int send(const char* buf, int len, enum ws_opcode opcode = WS_OPCODE_BINARY, bool fin = true);
|
||||
|
||||
// 分片发送
|
||||
int send(const char* buf, int len, int fragment, enum ws_opcode opcode = WS_OPCODE_BINARY);
|
||||
|
||||
// 关闭
|
||||
int close();
|
||||
|
||||
};
|
||||
|
||||
```
|
||||
123
third_party/libhv/docs/cn/EventLoop.md
vendored
Executable file
123
third_party/libhv/docs/cn/EventLoop.md
vendored
Executable file
@@ -0,0 +1,123 @@
|
||||
事件循环类
|
||||
|
||||
```c++
|
||||
|
||||
class EventLoop {
|
||||
|
||||
// 返回底层的loop结构体指针
|
||||
hloop_t* loop();
|
||||
|
||||
// 运行
|
||||
void run();
|
||||
// 停止
|
||||
void stop();
|
||||
// 暂停
|
||||
void pause();
|
||||
// 继续
|
||||
void resume();
|
||||
|
||||
// 设置定时器
|
||||
TimerID setTimer(int timeout_ms, TimerCallback cb, uint32_t repeat = INFINITE, TimerID timerID = INVALID_TIMER_ID);
|
||||
|
||||
// 设置一次性定时器
|
||||
TimerID setTimeout(int timeout_ms, TimerCallback cb);
|
||||
|
||||
// 设置永久性定时器
|
||||
TimerID setInterval(int interval_ms, TimerCallback cb);
|
||||
|
||||
// 杀掉定时器
|
||||
void killTimer(TimerID timerID);
|
||||
|
||||
// 重置定时器
|
||||
void resetTimer(TimerID timerID, int timeout_ms = 0);
|
||||
|
||||
// 返回事件循环所在的线程ID
|
||||
long tid();
|
||||
|
||||
// 是否在事件循环所在线程
|
||||
bool isInLoopThread();
|
||||
|
||||
// 断言在事件循环所在线程
|
||||
void assertInLoopThread();
|
||||
|
||||
// 运行在事件循环里
|
||||
void runInLoop(Functor fn);
|
||||
|
||||
// 队列在事件循环里
|
||||
void queueInLoop(Functor fn);
|
||||
|
||||
// 投递一个事件到事件循环
|
||||
void postEvent(EventCallback cb);
|
||||
|
||||
};
|
||||
|
||||
class EventLoopThread {
|
||||
|
||||
// 返回事件循环指针
|
||||
const EventLoopPtr& loop();
|
||||
|
||||
// 返回底层的loop结构体指针
|
||||
hloop_t* hloop();
|
||||
|
||||
// 是否运行中
|
||||
bool isRunning();
|
||||
|
||||
/* 开始运行
|
||||
* wait_thread_started: 是否阻塞等待线程开始
|
||||
* pre: 线程开始后执行的函数
|
||||
* post: 线程结束前执行的函数
|
||||
*/
|
||||
void start(bool wait_thread_started = true,
|
||||
Functor pre = Functor(),
|
||||
Functor post = Functor());
|
||||
|
||||
// 停止运行
|
||||
void stop(bool wait_thread_stopped = false);
|
||||
|
||||
// 等待线程退出
|
||||
void join();
|
||||
|
||||
};
|
||||
|
||||
class EventLoopThreadPool {
|
||||
|
||||
// 获取线程数量
|
||||
int threadNum();
|
||||
|
||||
// 设置线程数量
|
||||
void setThreadNum(int num);
|
||||
|
||||
// 返回下一个事件循环对象
|
||||
// 支持轮询、随机、最少连接数等负载均衡策略
|
||||
EventLoopPtr nextLoop(load_balance_e lb = LB_RoundRobin);
|
||||
|
||||
// 返回索引的事件循环对象
|
||||
EventLoopPtr loop(int idx = -1);
|
||||
|
||||
// 返回索引的底层loop结构体指针
|
||||
hloop_t* hloop(int idx = -1);
|
||||
|
||||
/* 开始运行
|
||||
* wait_threads_started: 是否阻塞等待所有线程开始
|
||||
* pre: 线程开始后执行的函数
|
||||
* post: 线程结束前执行的函数
|
||||
*/
|
||||
void start(bool wait_threads_started = false,
|
||||
std::function<void(const EventLoopPtr&)> pre = NULL,
|
||||
std::function<void(const EventLoopPtr&)> post = NULL);
|
||||
|
||||
// 停止运行
|
||||
void stop(bool wait_threads_stopped = false);
|
||||
|
||||
// 等待所有线程退出
|
||||
void join();
|
||||
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
测试代码见:
|
||||
|
||||
- [evpp/EventLoop_test.cpp](../../evpp/EventLoop_test.cpp)
|
||||
- [evpp/EventLoopThread_test.cpp](../../evpp/EventLoopThread_test.cpp)
|
||||
- [evpp/EventLoopThreadPool_test.cpp](../../evpp/EventLoopThreadPool_test.cpp)
|
||||
84
third_party/libhv/docs/cn/HttpClient.md
vendored
Executable file
84
third_party/libhv/docs/cn/HttpClient.md
vendored
Executable file
@@ -0,0 +1,84 @@
|
||||
HTTP 客户端类
|
||||
|
||||
```c++
|
||||
|
||||
class HttpClient {
|
||||
|
||||
// 设置超时
|
||||
int setTimeout(int timeout);
|
||||
|
||||
// 设置SSL/TLS
|
||||
int setSslCtx(hssl_ctx_t ssl_ctx);
|
||||
// 新建SSL/TLS
|
||||
int newSslCtx(hssl_ctx_opt_t* opt);
|
||||
|
||||
// 清除全部请求头部
|
||||
int clearHeaders();
|
||||
// 设置请求头部
|
||||
int setHeader(const char* key, const char* value);
|
||||
// 删除请求头部
|
||||
int delHeader(const char* key);
|
||||
// 获取请求头部
|
||||
const char* getHeader(const char* key);
|
||||
|
||||
// 设置http代理
|
||||
int setHttpProxy(const char* host, int port);
|
||||
// 设置https代理
|
||||
int setHttpsProxy(const char* host, int port);
|
||||
// 添加不走代理
|
||||
int addNoProxy(const char* host);
|
||||
|
||||
// 同步发送
|
||||
int send(HttpRequest* req, HttpResponse* resp);
|
||||
// 异步发送
|
||||
int sendAsync(HttpRequestPtr req, HttpResponseCallback resp_cb = NULL);
|
||||
|
||||
// 关闭连接 (HttpClient对象析构时会自动调用)
|
||||
int close();
|
||||
|
||||
};
|
||||
|
||||
namespace requests {
|
||||
|
||||
// 同步请求
|
||||
Response request(Request req);
|
||||
Response request(http_method method, const char* url, const http_body& body = NoBody, const http_headers& headers = DefaultHeaders);
|
||||
|
||||
// 上传文件
|
||||
Response uploadFile(const char* url, const char* filepath, http_method method = HTTP_POST, const http_headers& headers = DefaultHeaders);
|
||||
|
||||
// 通过 `multipart/form-data` 格式上传文件
|
||||
Response uploadFormFile(const char* url, const char* name, const char* filepath, std::map<std::string, std::string>& params = hv::empty_map, http_method method = HTTP_POST, const http_headers& headers = DefaultHeaders);
|
||||
|
||||
// 上传大文件(带上传进度回调)
|
||||
Response uploadLargeFile(const char* url, const char* filepath, upload_progress_cb progress_cb = NULL, http_method method = HTTP_POST, const http_headers& headers = DefaultHeaders);
|
||||
|
||||
// 下载文件 (更详细的断点续传示例代码见`examples/wget.cpp`)
|
||||
size_t downloadFile(const char* url, const char* filepath, download_progress_cb progress_cb = NULL);
|
||||
|
||||
// HEAD 请求
|
||||
Response head(const char* url, const http_headers& headers = DefaultHeaders);
|
||||
|
||||
// GET 请求
|
||||
Response get(const char* url, const http_headers& headers = DefaultHeaders);
|
||||
|
||||
// POST 请求
|
||||
Response post(const char* url, const http_body& body = NoBody, const http_headers& headers = DefaultHeaders);
|
||||
|
||||
// PUT 请求
|
||||
Response put(const char* url, const http_body& body = NoBody, const http_headers& headers = DefaultHeaders);
|
||||
|
||||
// PATCH 请求
|
||||
Response patch(const char* url, const http_body& body = NoBody, const http_headers& headers = DefaultHeaders);
|
||||
|
||||
// DELETE 请求
|
||||
Response Delete(const char* url, const http_headers& headers = DefaultHeaders);
|
||||
|
||||
// 异步请求
|
||||
int async(Request req, ResponseCallback resp_cb);
|
||||
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
测试代码见 [examples/http_client_test.cpp](../../examples/http_client_test.cpp)
|
||||
83
third_party/libhv/docs/cn/HttpContext.md
vendored
Executable file
83
third_party/libhv/docs/cn/HttpContext.md
vendored
Executable file
@@ -0,0 +1,83 @@
|
||||
```c++
|
||||
|
||||
class HttpContext {
|
||||
|
||||
/* 获取请求信息 */
|
||||
// 获取客户端IP
|
||||
std::string ip();
|
||||
// 获取客户端端口
|
||||
int port();
|
||||
// 获取请求method
|
||||
http_method method();
|
||||
// 获取请求url
|
||||
std::string url();
|
||||
// 获取请求path
|
||||
std::string path();
|
||||
// 获取请求host
|
||||
std::string host();
|
||||
// 获取请求头部
|
||||
const http_headers& headers();
|
||||
std::string header(const char* key, const std::string& defvalue = hv::empty_string);
|
||||
// 获取请求参数
|
||||
const hv::QueryParams& params();
|
||||
std::string param(const char* key, const std::string& defvalue = hv::empty_string);
|
||||
// 获取请求cookie
|
||||
const HttpCookie& cookie(const char* name);
|
||||
// 获取请求 `Content-Length`
|
||||
int length();
|
||||
// 获取请求 `Content-Type`
|
||||
http_content_type type();
|
||||
// 判断请求 `Content-Type`
|
||||
bool is(http_content_type content_type);
|
||||
// 获取请求body
|
||||
std::string& body();
|
||||
// 获取 `application/json` 格式数据
|
||||
const hv::Json& json();
|
||||
// 获取 `multipart/form-data` 格式数据
|
||||
const hv::MultiPart& form();
|
||||
std::string form(const char* name, const std::string& defvalue = hv::empty_string);
|
||||
// 获取 `application/x-www-urlencoded` 格式数据
|
||||
const hv::KeyValue& urlencoded();
|
||||
std::string urlencoded(const char* key, const std::string& defvalue = hv::empty_string);
|
||||
// 根据 `Content-Type` 获取对应格式数据
|
||||
template<typename T>
|
||||
T get(const char* key, T defvalue = 0);
|
||||
std::string get(const char* key, const std::string& defvalue = hv::empty_string);
|
||||
|
||||
/* 设置响应信息 */
|
||||
// 设置响应状态码
|
||||
void setStatus(http_status status);
|
||||
// 设置响应 `Content-Type`
|
||||
void setContentType(http_content_type type);
|
||||
// 设置响应头部
|
||||
void setHeader(const char* key, const std::string& value);
|
||||
// 设置响应cookie
|
||||
void setCookie(const HttpCookie& cookie);
|
||||
// 设置响应body
|
||||
void setBody(const std::string& body);
|
||||
template<typename T>
|
||||
// 根据 `Content-Type` 设置对应格式数据
|
||||
void set(const char* key, const T& value);
|
||||
|
||||
// 发送
|
||||
int send();
|
||||
int send(const std::string& str, http_content_type type = APPLICATION_JSON);
|
||||
// 发送文本数据
|
||||
int sendString(const std::string& str);
|
||||
// 发送二进制数据
|
||||
int sendData(void* data, int len, bool nocopy = true);
|
||||
// 发送文件
|
||||
int sendFile(const char* filepath);
|
||||
// 发送json数据
|
||||
template<typename T>
|
||||
int sendJson(const T& t);
|
||||
|
||||
// 重定向
|
||||
int redirect(const std::string& location, http_status status = HTTP_STATUS_FOUND);
|
||||
|
||||
// 主动关闭连接
|
||||
int close();
|
||||
|
||||
};
|
||||
|
||||
```
|
||||
110
third_party/libhv/docs/cn/HttpMessage.md
vendored
Executable file
110
third_party/libhv/docs/cn/HttpMessage.md
vendored
Executable file
@@ -0,0 +1,110 @@
|
||||
```c++
|
||||
|
||||
class HttpMessage {
|
||||
// 设置/获取头部
|
||||
void SetHeader(const char* key, const std::string& value);
|
||||
std::string GetHeader(const char* key, const std::string& defvalue = hv::empty_string);
|
||||
|
||||
// 添加/获取cookie
|
||||
void AddCookie(const HttpCookie& cookie);
|
||||
const HttpCookie& GetCookie(const std::string& name);
|
||||
|
||||
// 设置/获取 `Content-Type`
|
||||
void SetContentType(http_content_type type);
|
||||
http_content_type ContentType();
|
||||
|
||||
// 获取 `Content-Length`
|
||||
size_t ContentLength();
|
||||
|
||||
// 填充数据
|
||||
void SetBody(const std::string& body);
|
||||
// 获取数据
|
||||
const std::string& Body();
|
||||
// 解析数据
|
||||
int ParseBody();
|
||||
|
||||
// 填充/获取 `application/json` 格式数据
|
||||
template<typename T>
|
||||
int Json(const T& t);
|
||||
const hv::Json& GetJson();
|
||||
|
||||
// 填充/获取 `multipart/form-data` 格式数据
|
||||
template<typename T>
|
||||
void SetFormData(const char* name, const T& t);
|
||||
void SetFormFile(const char* name, const char* filepath);
|
||||
std::string GetFormData(const char* name, const std::string& defvalue = hv::empty_string);
|
||||
int SaveFormFile(const char* name, const char* path);
|
||||
|
||||
// 填充/获取 `application/x-www-urlencoded` 格式数据
|
||||
template<typename T>
|
||||
void SetUrlEncoded(const char* key, const T& t);
|
||||
std::string GetUrlEncoded(const char* key, const std::string& defvalue = hv::empty_string);
|
||||
|
||||
// 根据 `Content-Type` 填充对应格式数据
|
||||
template<typename T>
|
||||
void Set(const char* key, const T& value);
|
||||
// 根据 `Content-Type` 获取对应格式数据
|
||||
template<typename T>
|
||||
T Get(const char* key, T defvalue = 0);
|
||||
// 根据 `Content-Type` 获取对应格式数据并转换成字符串
|
||||
std::string GetString(const char* key, const std::string& = "");
|
||||
// 根据 `Content-Type` 获取对应格式数据并转换成Boolean类型
|
||||
bool GetBool(const char* key, bool defvalue = 0);
|
||||
// 根据 `Content-Type` 获取对应格式数据并转换成整型
|
||||
int64_t GetInt(const char* key, int64_t defvalue = 0);
|
||||
// 根据 `Content-Type` 获取对应格式数据并转换成浮点数
|
||||
double GetFloat(const char* key, double defvalue = 0);
|
||||
};
|
||||
|
||||
// HttpRequest 继承自 HttpMessage
|
||||
class HttpRequest : public HttpMessage {
|
||||
// 设置/获取method
|
||||
void SetMethod(const char* method);
|
||||
const char* Method();
|
||||
|
||||
// 设置URL
|
||||
void SetUrl(const char* url);
|
||||
// 获取URL
|
||||
const std::string& Url();
|
||||
// 解析URL
|
||||
void ParseUrl();
|
||||
// 获取Host
|
||||
std::string Host();
|
||||
// 获取Path
|
||||
std::string Path();
|
||||
|
||||
// 设置/获取参数
|
||||
template<typename T>
|
||||
void SetParam(const char* key, const T& t);
|
||||
std::string GetParam(const char* key, const std::string& defvalue = hv::empty_string);
|
||||
|
||||
// 设置代理
|
||||
void SetProxy(const char* host, int port);
|
||||
|
||||
// 设置认证
|
||||
void SetAuth(const std::string& auth);
|
||||
void SetBasicAuth(const std::string& username, const std::string& password);
|
||||
void SetBearerTokenAuth(const std::string& token);
|
||||
|
||||
// 设置请求超时
|
||||
void SetTimeout(int sec);
|
||||
// 设置连接超时
|
||||
void SetConnectTimeout(int sec);
|
||||
// 允许重定向
|
||||
void AllowRedirect(bool on = true);
|
||||
// 设置重试
|
||||
void SetRetry(int count = DEFAULT_HTTP_FAIL_RETRY_COUNT,
|
||||
int delay = DEFAULT_HTTP_FAIL_RETRY_DELAY);
|
||||
// 取消
|
||||
void Cancel();
|
||||
};
|
||||
|
||||
// HttpResponse 继承自 HttpMessage
|
||||
class HttpResponse : public HttpMessage {
|
||||
// 状态码
|
||||
http_status status_code;
|
||||
// 状态字符串
|
||||
const char* status_message();
|
||||
};
|
||||
|
||||
```
|
||||
140
third_party/libhv/docs/cn/HttpServer.md
vendored
Executable file
140
third_party/libhv/docs/cn/HttpServer.md
vendored
Executable file
@@ -0,0 +1,140 @@
|
||||
HTTP 服务端类
|
||||
|
||||
```c++
|
||||
|
||||
// HTTP服务类
|
||||
class HttpServer {
|
||||
|
||||
// 注册HTTP业务类
|
||||
void registerHttpService(HttpService* service);
|
||||
|
||||
// 设置监听主机
|
||||
void setHost(const char* host = "0.0.0.0");
|
||||
// 设置监听端口
|
||||
void setPort(int port = 0, int ssl_port = 0);
|
||||
// 设置监听文件描述符
|
||||
void setListenFD(int fd = -1, int ssl_fd = -1);
|
||||
|
||||
// 设置IO进程数 (仅`linux`下有效)
|
||||
void setProcessNum(int num);
|
||||
// 设置IO线程数
|
||||
void setThreadNum(int num);
|
||||
|
||||
// 设置SSL/TLS
|
||||
int setSslCtx(hssl_ctx_t ssl_ctx);
|
||||
// 新建SSL/TLS
|
||||
int newSslCtx(hssl_ctx_opt_t* opt);
|
||||
|
||||
// hooks
|
||||
// 事件循环开始时执行的回调函数
|
||||
std::function<void()> onWorkerStart;
|
||||
// 事件循环结束时执行的回调函数
|
||||
std::function<void()> onWorkerStop;
|
||||
|
||||
// 占用当前线程运行
|
||||
int run(bool wait = true);
|
||||
|
||||
// 不占用当前线程运行
|
||||
int start();
|
||||
|
||||
// 停止服务
|
||||
int stop();
|
||||
|
||||
};
|
||||
|
||||
// HTTP业务类
|
||||
class HttpService {
|
||||
|
||||
// 添加静态资源映射
|
||||
void Static(const char* path, const char* dir);
|
||||
|
||||
// 允许跨域访问
|
||||
void AllowCORS();
|
||||
|
||||
// 添加可信代理 (代理白名单)
|
||||
void AddTrustProxy(const char* host);
|
||||
|
||||
// 添加不可信代理 (代理黑名单)
|
||||
void AddNoProxy(const char* host);
|
||||
|
||||
// 开启正向转发代理
|
||||
void EnableForwardProxy();
|
||||
|
||||
// 添加反向代理映射
|
||||
void Proxy(const char* path, const char* url);
|
||||
|
||||
// 添加中间件
|
||||
void Use(Handler handlerFunc);
|
||||
|
||||
// 添加路由处理器
|
||||
void Handle(const char* httpMethod, const char* relativePath, Handler handlerFunc);
|
||||
|
||||
// 添加`HEAD`路由
|
||||
void HEAD(const char* relativePath, Handler handlerFunc);
|
||||
|
||||
// 添加`GET`路由
|
||||
void GET(const char* relativePath, Handler handlerFunc);
|
||||
|
||||
// 添加`POST`路由
|
||||
void POST(const char* relativePath, Handler handlerFunc);
|
||||
|
||||
// 添加`PUT`路由
|
||||
void PUT(const char* relativePath, Handler handlerFunc);
|
||||
|
||||
// 添加`DELETE`路由
|
||||
void Delete(const char* relativePath, Handler handlerFunc);
|
||||
|
||||
// 添加`PATCH`路由
|
||||
void PATCH(const char* relativePath, Handler handlerFunc);
|
||||
|
||||
// 添加任意`HTTP method`路由
|
||||
void Any(const char* relativePath, Handler handlerFunc);
|
||||
|
||||
// 返回注册的路由路径列表
|
||||
hv::StringList Paths();
|
||||
|
||||
// 处理流程:前处理器 -> 中间件 -> 处理器 -> 后处理器
|
||||
// preprocessor -> middleware -> processor -> postprocessor
|
||||
|
||||
// 数据成员
|
||||
http_handler preprocessor; // 前处理器
|
||||
http_handlers middleware; // 中间件
|
||||
http_handler processor; // 处理器
|
||||
http_handler postprocessor; // 后处理器
|
||||
std::string base_url; // 基本路径
|
||||
std::string document_root; // 文档根目录
|
||||
std::string home_page; // 主页
|
||||
std::string error_page; // 默认错误页
|
||||
std::string index_of; // 目录
|
||||
http_handler errorHandler; // 错误处理器
|
||||
|
||||
int proxy_connect_timeout; // 代理连接超时
|
||||
int proxy_read_timeout; // 代理读超时
|
||||
int proxy_write_timeout; // 代理写超时
|
||||
|
||||
int keepalive_timeout; // 长连接保活超时
|
||||
int max_file_cache_size; // 文件缓存最大尺寸
|
||||
int file_cache_stat_interval; // 文件缓存stat间隔,查询文件是否修改
|
||||
int file_cache_expired_time; // 文件缓存过期时间,过期自动释放
|
||||
|
||||
int limit_rate; // 下载速度限制
|
||||
|
||||
};
|
||||
|
||||
/* 几种`handler`处理函数区别说明: */
|
||||
|
||||
// 同步`handler`运行在IO线程
|
||||
typedef std::function<int(HttpRequest* req, HttpResponse* resp)> http_sync_handler;
|
||||
|
||||
// 异步`handler`运行在`hv::async`全局线程池,可通过`hv::async::startup`设置线程池属性
|
||||
typedef std::function<void(const HttpRequestPtr& req, const HttpResponseWriterPtr& writer)> http_async_handler;
|
||||
|
||||
// 上下文`handler`运行在IO线程,你可以很方便的将`HttpContextPtr`智能指针抛到你的消费者线程/线程池去处理
|
||||
typedef std::function<int(const HttpContextPtr& ctx)> http_ctx_handler;
|
||||
|
||||
// 中间状态`handler`运行在IO线程,用来实现大数据量的边接收边处理
|
||||
typedef std::function<int(const HttpContextPtr& ctx, http_parser_state state, const char* data, size_t size)> http_state_handler;
|
||||
|
||||
```
|
||||
|
||||
测试代码见 [examples/http_server_test.cpp](../../examples/http_server_test.cpp)
|
||||
18
third_party/libhv/docs/cn/README.md
vendored
Executable file
18
third_party/libhv/docs/cn/README.md
vendored
Executable file
@@ -0,0 +1,18 @@
|
||||
## c接口
|
||||
|
||||
- [hloop: 事件循环](hloop.md)
|
||||
- [hbase: 基础函数](hbase.md)
|
||||
- [hlog: 日志](hlog.md)
|
||||
|
||||
## c++接口
|
||||
|
||||
- [class EventLoop: 事件循环类](EventLoop.md)
|
||||
- [class Channel: 通道类](Channel.md)
|
||||
- [class TcpServer: TCP服务端类](TcpServer.md)
|
||||
- [class TcpClient: TCP客户端类](TcpClient.md)
|
||||
- [class UdpServer: UDP服务端类](UdpServer.md)
|
||||
- [class UdpClient: UDP客户端类](UdpClient.md)
|
||||
- [class HttpServer: HTTP服务端类](HttpServer.md)
|
||||
- [class HttpClient: HTTP客户端类](HttpClient.md)
|
||||
- [class WebSocketServer: WebSocket服务端类](WebSocketServer.md)
|
||||
- [class WebSocketClient: WebSocket客户端类](WebSocketClient.md)
|
||||
63
third_party/libhv/docs/cn/TcpClient.md
vendored
Executable file
63
third_party/libhv/docs/cn/TcpClient.md
vendored
Executable file
@@ -0,0 +1,63 @@
|
||||
TCP 客户端类
|
||||
|
||||
```c++
|
||||
|
||||
class TcpClient {
|
||||
|
||||
// 返回所在的事件循环
|
||||
const EventLoopPtr& loop();
|
||||
|
||||
// 创建套接字
|
||||
int createsocket(int remote_port, const char* remote_host = "127.0.0.1");
|
||||
int createsocket(struct sockaddr* remote_addr);
|
||||
|
||||
// 绑定端口
|
||||
int bind(int local_port, const char* local_host = "0.0.0.0");
|
||||
int bind(struct sockaddr* local_addr);
|
||||
|
||||
// 关闭套接字
|
||||
void closesocket();
|
||||
|
||||
// 开始运行
|
||||
void start(bool wait_threads_started = true);
|
||||
|
||||
// 停止运行
|
||||
void stop(bool wait_threads_stopped = true);
|
||||
|
||||
// 是否已连接
|
||||
bool isConnected();
|
||||
|
||||
// 发送
|
||||
int send(const void* data, int size);
|
||||
int send(Buffer* buf);
|
||||
int send(const std::string& str);
|
||||
|
||||
// 设置SSL/TLS加密通信
|
||||
int withTLS(hssl_ctx_opt_t* opt = NULL);
|
||||
|
||||
// 设置连接超时
|
||||
void setConnectTimeout(int ms);
|
||||
|
||||
// 设置重连
|
||||
void setReconnect(reconn_setting_t* setting);
|
||||
|
||||
// 是否是重连
|
||||
bool isReconnect();
|
||||
|
||||
// 设置拆包规则
|
||||
void setUnpack(unpack_setting_t* setting);
|
||||
|
||||
// 连接状态回调
|
||||
std::function<void(const TSocketChannelPtr&)> onConnection;
|
||||
|
||||
// 消息回调
|
||||
std::function<void(const TSocketChannelPtr&, Buffer*)> onMessage;
|
||||
|
||||
// 写完成回调
|
||||
std::function<void(const TSocketChannelPtr&, Buffer*)> onWriteComplete;
|
||||
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
测试代码见 [evpp/TcpClient_test.cpp](../../evpp/TcpClient_test.cpp)
|
||||
60
third_party/libhv/docs/cn/TcpServer.md
vendored
Executable file
60
third_party/libhv/docs/cn/TcpServer.md
vendored
Executable file
@@ -0,0 +1,60 @@
|
||||
TCP 服务端类
|
||||
|
||||
```c++
|
||||
|
||||
class TcpServer {
|
||||
|
||||
// 返回索引的事件循环
|
||||
EventLoopPtr loop(int idx = -1);
|
||||
|
||||
// 创建套接字
|
||||
int createsocket(int port, const char* host = "0.0.0.0");
|
||||
|
||||
// 关闭套接字
|
||||
void closesocket();
|
||||
|
||||
// 设置最大连接数
|
||||
void setMaxConnectionNum(uint32_t num);
|
||||
|
||||
// 设置负载均衡策略
|
||||
void setLoadBalance(load_balance_e lb);
|
||||
|
||||
// 设置线程数
|
||||
void setThreadNum(int num);
|
||||
|
||||
// 开始运行
|
||||
void start(bool wait_threads_started = true);
|
||||
|
||||
// 停止运行
|
||||
void stop(bool wait_threads_stopped = true);
|
||||
|
||||
// 设置SSL/TLS加密通信
|
||||
int withTLS(hssl_ctx_opt_t* opt = NULL);
|
||||
|
||||
// 设置拆包规则
|
||||
void setUnpack(unpack_setting_t* setting);
|
||||
|
||||
// 返回当前连接数
|
||||
size_t connectionNum();
|
||||
|
||||
// 遍历连接
|
||||
int foreachChannel(std::function<void(const TSocketChannelPtr& channel)> fn);
|
||||
|
||||
// 广播消息
|
||||
int broadcast(const void* data, int size);
|
||||
int broadcast(const std::string& str);
|
||||
|
||||
// 连接到来/断开回调
|
||||
std::function<void(const TSocketChannelPtr&)> onConnection;
|
||||
|
||||
// 消息回调
|
||||
std::function<void(const TSocketChannelPtr&, Buffer*)> onMessage;
|
||||
|
||||
// 写完成回调
|
||||
std::function<void(const TSocketChannelPtr&, Buffer*)> onWriteComplete;
|
||||
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
测试代码见 [evpp/TcpServer_test.cpp](../../evpp/TcpServer_test.cpp)
|
||||
42
third_party/libhv/docs/cn/UdpClient.md
vendored
Executable file
42
third_party/libhv/docs/cn/UdpClient.md
vendored
Executable file
@@ -0,0 +1,42 @@
|
||||
UDP 客户端类
|
||||
|
||||
```c++
|
||||
|
||||
class UdpClient {
|
||||
|
||||
// 返回所在的事件循环
|
||||
const EventLoopPtr& loop();
|
||||
|
||||
// 创建套接字
|
||||
int createsocket(int remote_port, const char* remote_host = "127.0.0.1");
|
||||
|
||||
// 绑定端口
|
||||
int bind(int local_port, const char* local_host = "0.0.0.0");
|
||||
|
||||
// 关闭套接字
|
||||
void closesocket();
|
||||
|
||||
// 开始运行
|
||||
void start(bool wait_threads_started = true);
|
||||
|
||||
// 停止运行
|
||||
void stop(bool wait_threads_stopped = true);
|
||||
|
||||
// 发送
|
||||
int sendto(const void* data, int size, struct sockaddr* peeraddr = NULL);
|
||||
int sendto(Buffer* buf, struct sockaddr* peeraddr = NULL);
|
||||
int sendto(const std::string& str, struct sockaddr* peeraddr = NULL);
|
||||
|
||||
// 设置KCP
|
||||
void setKcp(kcp_setting_t* setting);
|
||||
|
||||
// 消息回调
|
||||
std::function<void(const TSocketChannelPtr&, Buffer*)> onMessage;
|
||||
|
||||
// 写完成回调
|
||||
std::function<void(const TSocketChannelPtr&, Buffer*)> onWriteComplete;
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
测试代码见 [evpp/UdpClient_test.cpp](../../evpp/UdpClient_test.cpp)
|
||||
39
third_party/libhv/docs/cn/UdpServer.md
vendored
Executable file
39
third_party/libhv/docs/cn/UdpServer.md
vendored
Executable file
@@ -0,0 +1,39 @@
|
||||
UDP 服务端类
|
||||
|
||||
```c++
|
||||
|
||||
class UdpServer {
|
||||
|
||||
// 返回所在的事件循环
|
||||
const EventLoopPtr& loop();
|
||||
|
||||
// 创建套接字
|
||||
int createsocket(int port, const char* host = "0.0.0.0");
|
||||
|
||||
// 关闭套接字
|
||||
void closesocket();
|
||||
|
||||
// 开始运行
|
||||
void start(bool wait_threads_started = true);
|
||||
|
||||
// 停止运行
|
||||
void stop(bool wait_threads_stopped = true);
|
||||
|
||||
// 发送
|
||||
int sendto(const void* data, int size, struct sockaddr* peeraddr = NULL);
|
||||
int sendto(Buffer* buf, struct sockaddr* peeraddr = NULL);
|
||||
int sendto(const std::string& str, struct sockaddr* peeraddr = NULL);
|
||||
|
||||
// 设置KCP
|
||||
void setKcp(kcp_setting_t* setting);
|
||||
|
||||
// 消息回调
|
||||
std::function<void(const TSocketChannelPtr&, Buffer*)> onMessage;
|
||||
|
||||
// 写完成回调
|
||||
std::function<void(const TSocketChannelPtr&, Buffer*)> onWriteComplete;
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
测试代码见 [evpp/UdpServer_test.cpp](../../evpp/UdpServer_test.cpp)
|
||||
37
third_party/libhv/docs/cn/WebSocketClient.md
vendored
Executable file
37
third_party/libhv/docs/cn/WebSocketClient.md
vendored
Executable file
@@ -0,0 +1,37 @@
|
||||
WebSocket 客户端类
|
||||
|
||||
```c++
|
||||
|
||||
class WebSocketClient {
|
||||
|
||||
// 打开回调
|
||||
std::function<void()> onopen;
|
||||
// 关闭回调
|
||||
std::function<void()> onclose;
|
||||
// 消息回调
|
||||
std::function<void(const std::string& msg)> onmessage;
|
||||
|
||||
// 打开
|
||||
int open(const char* url, const http_headers& headers = DefaultHeaders);
|
||||
|
||||
// 关闭
|
||||
int close();
|
||||
|
||||
// 发送
|
||||
int send(const std::string& msg);
|
||||
int send(const char* buf, int len, enum ws_opcode opcode = WS_OPCODE_BINARY);
|
||||
|
||||
// 设置心跳间隔
|
||||
void setPingInterval(int ms);
|
||||
|
||||
// 设置WebSocket握手阶段的HTTP请求
|
||||
void setHttpRequest(const HttpRequestPtr& req);
|
||||
|
||||
// 获取WebSocket握手阶段的HTTP响应
|
||||
const HttpResponsePtr& getHttpResponse();
|
||||
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
测试代码见 [examples/websocket_client_test.cpp](../../examples/websocket_client_test.cpp)
|
||||
30
third_party/libhv/docs/cn/WebSocketServer.md
vendored
Executable file
30
third_party/libhv/docs/cn/WebSocketServer.md
vendored
Executable file
@@ -0,0 +1,30 @@
|
||||
WebSocket 服务端类
|
||||
|
||||
```c++
|
||||
|
||||
// WebSocketServer 继承自 HttpServer
|
||||
class WebSocketServer : public HttpServer {
|
||||
|
||||
// 注册WebSocket业务类
|
||||
void registerWebSocketService(WebSocketService* service);
|
||||
|
||||
};
|
||||
|
||||
// WebSocket业务类
|
||||
struct WebSocketService {
|
||||
// 打开回调
|
||||
std::function<void(const WebSocketChannelPtr&, const HttpRequestPtr&)> onopen;
|
||||
|
||||
// 消息回调
|
||||
std::function<void(const WebSocketChannelPtr&, const std::string&)> onmessage;
|
||||
|
||||
// 关闭回调
|
||||
std::function<void(const WebSocketChannelPtr&)> onclose;
|
||||
|
||||
// 心跳间隔
|
||||
int ping_interval;
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
测试代码见 [examples/websocket_server_test.cpp](../../examples/websocket_server_test.cpp)
|
||||
111
third_party/libhv/docs/cn/hbase.md
vendored
Executable file
111
third_party/libhv/docs/cn/hbase.md
vendored
Executable file
@@ -0,0 +1,111 @@
|
||||
一些基础函数
|
||||
|
||||
```c
|
||||
|
||||
/* hv内存分配/释放函数 */
|
||||
void* hv_malloc(size_t size);
|
||||
void* hv_realloc(void* oldptr, size_t newsize, size_t oldsize);
|
||||
void* hv_calloc(size_t nmemb, size_t size);
|
||||
void* hv_zalloc(size_t size);
|
||||
void hv_free(void* ptr);
|
||||
|
||||
// 使用hv分配内存次数
|
||||
long hv_alloc_cnt();
|
||||
|
||||
// 使用hv释放内存次数
|
||||
long hv_free_cnt();
|
||||
|
||||
/* 字符串操作 */
|
||||
// 字符串转大写
|
||||
char* hv_strupper(char* str);
|
||||
// 字符串转小写
|
||||
char* hv_strlower(char* str);
|
||||
// 字符串翻转
|
||||
char* hv_strreverse(char* str);
|
||||
|
||||
// 判断字符串是否以xxx开头
|
||||
bool hv_strstartswith(const char* str, const char* start);
|
||||
|
||||
// 判断字符串是否以xxx结尾
|
||||
bool hv_strendswith(const char* str, const char* end);
|
||||
|
||||
// 判断字符串是否包含xxx
|
||||
bool hv_strcontains(const char* str, const char* sub);
|
||||
|
||||
// 安全的strncpy
|
||||
char* hv_strncpy(char* dest, const char* src, size_t n);
|
||||
|
||||
// 安全的strncat
|
||||
char* hv_strncat(char* dest, const char* src, size_t n);
|
||||
|
||||
// 字符查找
|
||||
char* hv_strnchr(const char* s, char c, size_t n);
|
||||
|
||||
// 查找最后一个点(通常用于提取文件后缀)
|
||||
#define hv_strrchr_dot(str) strrchr(str, '.')
|
||||
|
||||
// 查找最后的路径(通常用于分离目录和文件)
|
||||
char* hv_strrchr_dir(const char* filepath);
|
||||
|
||||
// 获取文件名(利用了上面的strrchr_dir)
|
||||
const char* hv_basename(const char* filepath);
|
||||
|
||||
// 获取文件后缀(利用了上面的strrchr_dot)
|
||||
const char* hv_suffixname(const char* filename);
|
||||
|
||||
/* 文件&目录 */
|
||||
// mkdir -p: 创建目录
|
||||
int hv_mkdir_p(const char* dir);
|
||||
// rmdir -p: 删除目录
|
||||
int hv_rmdir_p(const char* dir);
|
||||
|
||||
// 判断路径是否存在
|
||||
bool hv_exists(const char* path);
|
||||
|
||||
// 判断是否是目录
|
||||
bool hv_isdir(const char* path);
|
||||
|
||||
// 判断是否是文件
|
||||
bool hv_isfile(const char* path);
|
||||
|
||||
// 判断是否是链接
|
||||
bool hv_islink(const char* path);
|
||||
|
||||
// 获取文件大小
|
||||
size_t hv_filesize(const char* filepath);
|
||||
|
||||
// 获取可执行文件绝对路径,例如/usr/local/bin/httpd
|
||||
char* get_executable_path(char* buf, int size);
|
||||
|
||||
// 获取可执行文件所在目录,例如/usr/local/bin
|
||||
char* get_executable_dir(char* buf, int size);
|
||||
|
||||
// 获取可执行文件名,例如httpd
|
||||
char* get_executable_file(char* buf, int size);
|
||||
|
||||
// 获取运行目录,例如/home/www/html
|
||||
char* get_run_dir(char* buf, int size);
|
||||
|
||||
// 返回一个随机数
|
||||
int hv_rand(int min, int max);
|
||||
|
||||
// 返回一个随机字符串
|
||||
char* hv_random_string(char *buf, int len);
|
||||
|
||||
// 1 y on yes true enable返回true(通常用于配置文件)
|
||||
bool hv_getboolean(const char* str);
|
||||
|
||||
// 解析size字符串
|
||||
// 1T2G3M4K5B => ?B
|
||||
size_t hv_parse_size(const char* str);
|
||||
|
||||
// 解析时间字符串
|
||||
// 1w2d3h4m5s => ?s
|
||||
time_t hv_parse_time(const char* str);
|
||||
|
||||
// 解析url字符串
|
||||
int hv_parse_url(hurl_t* stURL, const char* strURL);
|
||||
|
||||
```
|
||||
|
||||
单元测试代码见 [unittest/hbase_test.c](../../unittest/hbase_test.c)
|
||||
111
third_party/libhv/docs/cn/hlog.md
vendored
Executable file
111
third_party/libhv/docs/cn/hlog.md
vendored
Executable file
@@ -0,0 +1,111 @@
|
||||
日志
|
||||
|
||||
```c
|
||||
|
||||
// 标准输出日志
|
||||
void stdout_logger(int loglevel, const char* buf, int len);
|
||||
|
||||
// 标准错误日志
|
||||
void stderr_logger(int loglevel, const char* buf, int len);
|
||||
|
||||
// 文件日志
|
||||
void file_logger(int loglevel, const char* buf, int len);
|
||||
|
||||
// 网络日志(定义在event/nlog.h头文件里)
|
||||
// void network_logger(int loglevel, const char* buf, int len);
|
||||
|
||||
// 创建日志器
|
||||
logger_t* logger_create();
|
||||
|
||||
// 销毁日志器
|
||||
void logger_destroy(logger_t* logger);
|
||||
|
||||
// 设置日志处理器
|
||||
void logger_set_handler(logger_t* logger, logger_handler fn);
|
||||
|
||||
// 设置日志等级
|
||||
void logger_set_level(logger_t* logger, int level);
|
||||
// level = [VERBOSE,DEBUG,INFO,WARN,ERROR,FATAL,SILENT]
|
||||
void logger_set_level_by_str(logger_t* logger, const char* level);
|
||||
|
||||
/*
|
||||
* 设置日志格式
|
||||
* format = "%y-%m-%d %H:%M:%S.%z %L %s"
|
||||
* message = "2020-01-02 03:04:05.067 DEBUG message"
|
||||
* %y year
|
||||
* %m month
|
||||
* %d day
|
||||
* %H hour
|
||||
* %M min
|
||||
* %S sec
|
||||
* %z ms
|
||||
* %Z us
|
||||
* %l First character of level
|
||||
* %L All characters of level
|
||||
* %s message
|
||||
* %% %
|
||||
*/
|
||||
void logger_set_format(logger_t* logger, const char* format);
|
||||
|
||||
// 设置日志缓存大小
|
||||
void logger_set_max_bufsize(logger_t* logger, unsigned int bufsize);
|
||||
|
||||
// 启用日志颜色
|
||||
void logger_enable_color(logger_t* logger, int on);
|
||||
|
||||
// 日志打印
|
||||
int logger_print(logger_t* logger, int level, const char* fmt, ...);
|
||||
|
||||
// 设置日志文件
|
||||
void logger_set_file(logger_t* logger, const char* filepath);
|
||||
|
||||
// 设置日志文件大小
|
||||
void logger_set_max_filesize(logger_t* logger, unsigned long long filesize);
|
||||
// 16, 16M, 16MB
|
||||
void logger_set_max_filesize_by_str(logger_t* logger, const char* filesize);
|
||||
|
||||
// 设置日志文件保留天数
|
||||
void logger_set_remain_days(logger_t* logger, int days);
|
||||
|
||||
// 启用每次写日志文件立即刷新到磁盘(即每次都调用fsync,会增加IO耗时,影响性能)
|
||||
void logger_enable_fsync(logger_t* logger, int on);
|
||||
|
||||
// 刷新缓存到磁盘(如对日志文件实时性有必要的,可使用定时器定时刷新到磁盘)
|
||||
void logger_fsync(logger_t* logger);
|
||||
|
||||
// 获取当前日志文件路径
|
||||
const char* logger_get_cur_file(logger_t* logger);
|
||||
|
||||
// hlog: 默认的日志器
|
||||
logger_t* hv_default_logger();
|
||||
|
||||
// 销毁默认的日志器
|
||||
void hv_destroy_default_logger(void);
|
||||
|
||||
// 对默认日志器hlog的一些便利操作宏
|
||||
#define hlog hv_default_logger()
|
||||
#define hlog_destory() hv_destroy_default_logger()
|
||||
/* 禁用hv的默认日志 */
|
||||
#define hlog_disable() logger_set_level(hlog, LOG_LEVEL_SILENT)
|
||||
#define hlog_set_file(filepath) logger_set_file(hlog, filepath)
|
||||
#define hlog_set_level(level) logger_set_level(hlog, level)
|
||||
#define hlog_set_level_by_str(level) logger_set_level_by_str(hlog, level)
|
||||
#define hlog_set_handler(fn) logger_set_handler(hlog, fn)
|
||||
#define hlog_set_format(format) logger_set_format(hlog, format)
|
||||
#define hlog_set_max_filesize(filesize) logger_set_max_filesize(hlog, filesize)
|
||||
#define hlog_set_max_filesize_by_str(filesize) logger_set_max_filesize_by_str(hlog, filesize)
|
||||
#define hlog_set_remain_days(days) logger_set_remain_days(hlog, days)
|
||||
#define hlog_enable_fsync() logger_enable_fsync(hlog, 1)
|
||||
#define hlog_disable_fsync() logger_enable_fsync(hlog, 0)
|
||||
#define hlog_fsync() logger_fsync(hlog)
|
||||
#define hlog_get_cur_file() logger_get_cur_file(hlog)
|
||||
|
||||
#define hlogd(fmt, ...) logger_print(hlog, LOG_LEVEL_DEBUG, fmt " [%s:%d:%s]\n", ## __VA_ARGS__, __FILENAME__, __LINE__, __FUNCTION__)
|
||||
#define hlogi(fmt, ...) logger_print(hlog, LOG_LEVEL_INFO, fmt " [%s:%d:%s]\n", ## __VA_ARGS__, __FILENAME__, __LINE__, __FUNCTION__)
|
||||
#define hlogw(fmt, ...) logger_print(hlog, LOG_LEVEL_WARN, fmt " [%s:%d:%s]\n", ## __VA_ARGS__, __FILENAME__, __LINE__, __FUNCTION__)
|
||||
#define hloge(fmt, ...) logger_print(hlog, LOG_LEVEL_ERROR, fmt " [%s:%d:%s]\n", ## __VA_ARGS__, __FILENAME__, __LINE__, __FUNCTION__)
|
||||
#define hlogf(fmt, ...) logger_print(hlog, LOG_LEVEL_FATAL, fmt " [%s:%d:%s]\n", ## __VA_ARGS__, __FILENAME__, __LINE__, __FUNCTION__)
|
||||
|
||||
```
|
||||
|
||||
测试代码见 [examples/hloop_test.c](../../examples/hloop_test.c)
|
||||
646
third_party/libhv/docs/cn/hloop.md
vendored
Executable file
646
third_party/libhv/docs/cn/hloop.md
vendored
Executable file
@@ -0,0 +1,646 @@
|
||||
事件循环和IO多路复用机制介绍
|
||||
|
||||
事件循环是`libevent、libev、libuv、libhv`这类网络库里最核心的概念,即在事件循环里处理IO读写事件、定时器事件、自定义事件等各种事件;<br>
|
||||
IO多路复用即在一个IO线程监听多个fd,如最早期的`select`、后来的`poll`,`linux的epoll`、`windows的iocp`、`bsd的kqueue`、`solaris的port`等,都属于IO多路复用机制。<br>
|
||||
非阻塞NIO搭配IO多路复用机制就是高并发的钥匙。<br>
|
||||
`libhv`下的`event`模块正是封装了多种平台的IO多路复用机制,提供了统一的事件接口,是`libhv`的核心模块。<br>
|
||||
|
||||
`hloop.h`: 事件循环模块对外头文件。<br>
|
||||
|
||||
```c
|
||||
|
||||
// 事件结构体
|
||||
struct hevent_s {
|
||||
hloop_t* loop; // 事件所属循环
|
||||
hevent_type_e event_type; // 事件类型
|
||||
uint64_t event_id; // 事件ID
|
||||
hevent_cb cb; // 事件回调
|
||||
void* userdata; // 用户数据
|
||||
void* privdata; // 私有数据
|
||||
struct hevent_s* pending_next; // 指向下一个事件,用于实现事件队列
|
||||
int priority; // 事件优先级
|
||||
};
|
||||
|
||||
// 设置事件ID
|
||||
#define hevent_set_id(ev, id) ((hevent_t*)(ev))->event_id = id
|
||||
// 设置事件回调
|
||||
#define hevent_set_cb(ev, cb) ((hevent_t*)(ev))->cb = cb
|
||||
// 设置事件优先级
|
||||
#define hevent_set_priority(ev, prio) ((hevent_t*)(ev))->priority = prio
|
||||
// 设置事件用户数据
|
||||
#define hevent_set_userdata(ev, udata) ((hevent_t*)(ev))->userdata = (void*)udata
|
||||
|
||||
// 获取事件所属循环
|
||||
#define hevent_loop(ev) (((hevent_t*)(ev))->loop)
|
||||
// 获取事件类型
|
||||
#define hevent_type(ev) (((hevent_t*)(ev))->event_type)
|
||||
// 获取事件ID
|
||||
#define hevent_id(ev) (((hevent_t*)(ev))->event_id)
|
||||
// 获取事件回调
|
||||
#define hevent_cb(ev) (((hevent_t*)(ev))->cb)
|
||||
// 获取事件优先级
|
||||
#define hevent_priority(ev) (((hevent_t*)(ev))->priority)
|
||||
// 获取事件用户数据
|
||||
#define hevent_userdata(ev) (((hevent_t*)(ev))->userdata)
|
||||
|
||||
// hio_t、htimer_t、hsignal_t、hidle_t皆是继承自hevent_t,继承上面的数据成员和函数方法
|
||||
|
||||
// 新建事件循环
|
||||
hloop_t* hloop_new(int flags DEFAULT(HLOOP_FLAG_AUTO_FREE));
|
||||
|
||||
// 释放事件循环
|
||||
void hloop_free(hloop_t** pp);
|
||||
|
||||
// 运行事件循环
|
||||
int hloop_run(hloop_t* loop);
|
||||
|
||||
// 停止事件循环
|
||||
int hloop_stop(hloop_t* loop);
|
||||
|
||||
// 暂停事件循环
|
||||
int hloop_pause(hloop_t* loop);
|
||||
|
||||
// 继续事件循环
|
||||
int hloop_resume(hloop_t* loop);
|
||||
|
||||
// 唤醒事件循环
|
||||
int hloop_wakeup(hloop_t* loop);
|
||||
|
||||
// 返回事件循环状态
|
||||
hloop_status_e hloop_status(hloop_t* loop);
|
||||
|
||||
// 更新事件循环里的时间
|
||||
void hloop_update_time(hloop_t* loop);
|
||||
|
||||
// 返回事件循环里记录的时间
|
||||
uint64_t hloop_now(hloop_t* loop); // s
|
||||
uint64_t hloop_now_ms(hloop_t* loop); // ms
|
||||
uint64_t hloop_now_us(hloop_t* loop); // us
|
||||
|
||||
// 返回事件循环所在进程ID
|
||||
long hloop_pid(hloop_t* loop);
|
||||
|
||||
// 返回事件循环所在线程ID
|
||||
long hloop_tid(hloop_t* loop);
|
||||
|
||||
// 返回事件循环的循环次数
|
||||
uint64_t hloop_count(hloop_t* loop);
|
||||
|
||||
// 返回事件循环里激活的IO事件数量
|
||||
uint32_t hloop_nios(hloop_t* loop);
|
||||
|
||||
// 返回事件循环里激活的定时器事件数量
|
||||
uint32_t hloop_ntimers(hloop_t* loop);
|
||||
|
||||
// 返回事件循环里激活的空闲事件数量
|
||||
uint32_t hloop_nidles(hloop_t* loop);
|
||||
|
||||
// 返回事件循环里激活的事件数量
|
||||
uint32_t hloop_nactives(hloop_t* loop);
|
||||
|
||||
// 设置事件循环的用户数据
|
||||
void hloop_set_userdata(hloop_t* loop, void* userdata);
|
||||
|
||||
// 获取事件循环的用户数据
|
||||
void* hloop_userdata(hloop_t* loop);
|
||||
|
||||
// 投递事件
|
||||
void hloop_post_event(hloop_t* loop, hevent_t* ev);
|
||||
|
||||
// 添加信号处理
|
||||
hsignal_t* hsignal_add(hloop_t* loop, hsignal_cb cb, int signo);
|
||||
|
||||
// 删除信号处理
|
||||
void hsignal_del(hsignal_t* sig);
|
||||
|
||||
// 添加空闲事件
|
||||
hidle_t* hidle_add(hloop_t* loop, hidle_cb cb, uint32_t repeat DEFAULT(INFINITE));
|
||||
|
||||
// 删除空闲事件
|
||||
void hidle_del(hidle_t* idle);
|
||||
|
||||
// 添加超时定时器
|
||||
htimer_t* htimer_add(hloop_t* loop, htimer_cb cb, uint32_t timeout_ms, uint32_t repeat DEFAULT(INFINITE));
|
||||
|
||||
// 添加时间定时器
|
||||
htimer_t* htimer_add_period(hloop_t* loop, htimer_cb cb,
|
||||
int8_t minute DEFAULT(0), int8_t hour DEFAULT(-1), int8_t day DEFAULT(-1),
|
||||
int8_t week DEFAULT(-1), int8_t month DEFAULT(-1), uint32_t repeat DEFAULT(INFINITE));
|
||||
|
||||
// 删除定时器
|
||||
void htimer_del(htimer_t* timer);
|
||||
|
||||
// 重置定时器
|
||||
void htimer_reset(htimer_t* timer, uint32_t timeout_ms DEFAULT(0));
|
||||
|
||||
// 返回IO多路复用引擎 (select、poll、epoll、etc.)
|
||||
const char* hio_engine();
|
||||
|
||||
// 获取IO对象
|
||||
hio_t* hio_get(hloop_t* loop, int fd);
|
||||
|
||||
// 添加IO读写事件
|
||||
int hio_add(hio_t* io, hio_cb cb, int events DEFAULT(HV_READ));
|
||||
|
||||
// 删除IO读写事件
|
||||
int hio_del(hio_t* io, int events DEFAULT(HV_RDWR));
|
||||
|
||||
// 将IO对象从当前所属事件循环中剥离
|
||||
void hio_detach(/*hloop_t* loop,*/ hio_t* io);
|
||||
|
||||
// 将IO对象关联到新的事件循环
|
||||
void hio_attach(hloop_t* loop, hio_t* io);
|
||||
|
||||
// hio_detach 和 hio_attach 的示例代码见 examples/multi-thread/one-acceptor-multi-workers.c
|
||||
/*
|
||||
void new_conn_event(hevent_t* ev) {
|
||||
hloop_t* loop = ev->loop;
|
||||
hio_t* io = (hio_t*)hevent_userdata(ev);
|
||||
// 关联到新的worker事件循环
|
||||
hio_attach(loop, io);
|
||||
}
|
||||
|
||||
void on_accpet(hio_t* io) {
|
||||
// 从acceptor所在事件循环中剥离
|
||||
hio_detach(io);
|
||||
|
||||
// 将新的连接按照负载均衡策略分发到worker线程
|
||||
hloop_t* worker_loop = get_one_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);
|
||||
}
|
||||
*/
|
||||
|
||||
// 判断fd是否存在于事件循环
|
||||
bool hio_exists(hloop_t* loop, int fd);
|
||||
|
||||
// 返回一个唯一标示ID
|
||||
uint32_t hio_id (hio_t* io);
|
||||
|
||||
// 返回文件描述符
|
||||
int hio_fd (hio_t* io);
|
||||
|
||||
// 返回错误码
|
||||
int hio_error (hio_t* io);
|
||||
|
||||
// 返回添加的事件
|
||||
int hio_events (hio_t* io);
|
||||
|
||||
// 获取返回的事件
|
||||
int hio_revents (hio_t* io);
|
||||
|
||||
// 返回IO类型
|
||||
hio_type_e hio_type (hio_t* io);
|
||||
|
||||
// 返回本地地址
|
||||
struct sockaddr* hio_localaddr(hio_t* io);
|
||||
|
||||
// 返回对端地址
|
||||
struct sockaddr* hio_peeraddr (hio_t* io);
|
||||
|
||||
// 设置上下文
|
||||
void hio_set_context(hio_t* io, void* ctx);
|
||||
|
||||
// 获取上下文
|
||||
void* hio_context(hio_t* io);
|
||||
|
||||
// 是否已打开
|
||||
bool hio_is_opened(hio_t* io);
|
||||
|
||||
// 是否已连接
|
||||
bool hio_is_connected(hio_t* io);
|
||||
|
||||
// 是否已关闭
|
||||
bool hio_is_closed(hio_t* io);
|
||||
|
||||
// 设置读缓存
|
||||
void hio_set_readbuf(hio_t* io, void* buf, size_t len);
|
||||
|
||||
// 获取读缓存
|
||||
hio_readbuf_t* hio_get_readbuf(hio_t* io);
|
||||
|
||||
// 设置最大读缓存
|
||||
void hio_set_max_read_bufsize (hio_t* io, uint32_t size);
|
||||
|
||||
// 设置最大写缓存
|
||||
void hio_set_max_write_bufsize(hio_t* io, uint32_t size);
|
||||
|
||||
// 获取当前写缓存大小
|
||||
size_t hio_write_bufsize(hio_t* io);
|
||||
|
||||
// 判断是否写完成
|
||||
#define hio_write_is_complete(io) (hio_write_bufsize(io) == 0)
|
||||
|
||||
// 获取最后读的时间
|
||||
uint64_t hio_last_read_time(hio_t* io); // ms
|
||||
|
||||
// 获取最后写的时间
|
||||
uint64_t hio_last_write_time(hio_t* io); // ms
|
||||
|
||||
// 设置accept回调
|
||||
void hio_setcb_accept (hio_t* io, haccept_cb accept_cb);
|
||||
// 设置连接回调
|
||||
void hio_setcb_connect (hio_t* io, hconnect_cb connect_cb);
|
||||
// 设置读回调
|
||||
void hio_setcb_read (hio_t* io, hread_cb read_cb);
|
||||
// 设置写回调
|
||||
void hio_setcb_write (hio_t* io, hwrite_cb write_cb);
|
||||
// 设置关闭回调
|
||||
void hio_setcb_close (hio_t* io, hclose_cb close_cb);
|
||||
|
||||
// 获取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);
|
||||
|
||||
// 开启SSL/TLS加密通信
|
||||
int hio_enable_ssl(hio_t* io);
|
||||
// 是否SSL/TLS加密通信
|
||||
bool hio_is_ssl(hio_t* io);
|
||||
// 设置SSL
|
||||
int hio_set_ssl (hio_t* io, hssl_t ssl);
|
||||
// 设置SSL_CTX
|
||||
int hio_set_ssl_ctx(hio_t* io, hssl_ctx_t ssl_ctx);
|
||||
// 新建SSL_CTX
|
||||
int hio_new_ssl_ctx(hio_t* io, hssl_ctx_opt_t* opt);
|
||||
// 获取SSL
|
||||
hssl_t hio_get_ssl(hio_t* io);
|
||||
// 获取SSL_CTX
|
||||
hssl_ctx_t hio_get_ssl_ctx(hio_t* io);
|
||||
// 设置主机名
|
||||
int hio_set_hostname(hio_t* io, const char* hostname);
|
||||
// 获取主机名
|
||||
const char* hio_get_hostname(hio_t* io);
|
||||
|
||||
// 设置连接超时
|
||||
void hio_set_connect_timeout(hio_t* io, int timeout_ms DEFAULT(HIO_DEFAULT_CONNECT_TIMEOUT));
|
||||
// 设置关闭超时 (说明:非阻塞写队列非空时,需要等待写完成再关闭)
|
||||
void hio_set_close_timeout(hio_t* io, int timeout_ms DEFAULT(HIO_DEFAULT_CLOSE_TIMEOUT));
|
||||
// 设置读超时 (一段时间没有数据到来便自动关闭连接)
|
||||
void hio_set_read_timeout(hio_t* io, int timeout_ms);
|
||||
// 设置写超时 (一段时间没有数据发送便自动关闭连接)
|
||||
void hio_set_write_timeout(hio_t* io, int timeout_ms);
|
||||
// 设置keepalive超时 (一段时间没有数据收发便自动关闭连接)
|
||||
void hio_set_keepalive_timeout(hio_t* io, int timeout_ms DEFAULT(HIO_DEFAULT_KEEPALIVE_TIMEOUT));
|
||||
|
||||
// 设置心跳 (定时发送心跳包)
|
||||
typedef void (*hio_send_heartbeat_fn)(hio_t* io);
|
||||
void hio_set_heartbeat(hio_t* io, int interval_ms, hio_send_heartbeat_fn fn);
|
||||
|
||||
// 接收连接
|
||||
// hio_add(io, HV_READ) => accept => haccept_cb
|
||||
int hio_accept (hio_t* io);
|
||||
|
||||
// 连接
|
||||
// connect => hio_add(io, HV_WRITE) => hconnect_cb
|
||||
int hio_connect(hio_t* io);
|
||||
|
||||
// 读
|
||||
// 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)
|
||||
|
||||
// 读一次
|
||||
// hio_read_start => hread_cb => hio_read_stop
|
||||
int hio_read_once (hio_t* io);
|
||||
|
||||
// 读取直到指定长度
|
||||
// hio_read_once => hread_cb(len)
|
||||
int hio_read_until_length(hio_t* io, unsigned int len);
|
||||
|
||||
// 读取直到遇到分隔符
|
||||
// hio_read_once => hread_cb(...delim)
|
||||
int hio_read_until_delim (hio_t* io, unsigned char delim);
|
||||
|
||||
// 读取一行
|
||||
#define hio_readline(io) hio_read_until_delim(io, '\n')
|
||||
|
||||
// 读取字符串
|
||||
#define hio_readstring(io) hio_read_until_delim(io, '\0')
|
||||
|
||||
// 读取N个字节
|
||||
#define hio_readbytes(io, len) hio_read_until_length(io, len)
|
||||
#define hio_read_until(io, len) hio_read_until_length(io, len)
|
||||
|
||||
// 写
|
||||
// hio_try_write => hio_add(io, HV_WRITE) => write => hwrite_cb
|
||||
int hio_write (hio_t* io, const void* buf, size_t len);
|
||||
|
||||
// 关闭
|
||||
// hio_del(io, HV_RDWR) => close => hclose_cb
|
||||
int hio_close (hio_t* io);
|
||||
|
||||
// 异步关闭 (投递一个close事件)
|
||||
// NOTE: hloop_post_event(hio_close_event)
|
||||
int hio_close_async(hio_t* io);
|
||||
|
||||
//------------------高等级的接口-------------------------------------------
|
||||
// 读
|
||||
// hio_get -> hio_set_readbuf -> hio_setcb_read -> hio_read
|
||||
hio_t* hread (hloop_t* loop, int fd, void* buf, size_t len, hread_cb read_cb);
|
||||
// 写
|
||||
// hio_get -> hio_setcb_write -> hio_write
|
||||
hio_t* hwrite (hloop_t* loop, int fd, const void* buf, size_t len, hwrite_cb write_cb DEFAULT(NULL));
|
||||
// 关闭
|
||||
// hio_get -> hio_close
|
||||
void hclose (hloop_t* loop, int fd);
|
||||
|
||||
// tcp
|
||||
// 接收连接
|
||||
// hio_get -> hio_setcb_accept -> hio_accept
|
||||
hio_t* haccept (hloop_t* loop, int listenfd, haccept_cb accept_cb);
|
||||
// 连接
|
||||
// hio_get -> hio_setcb_connect -> hio_connect
|
||||
hio_t* hconnect (hloop_t* loop, int connfd, hconnect_cb connect_cb);
|
||||
// 接收
|
||||
// hio_get -> hio_set_readbuf -> hio_setcb_read -> hio_read
|
||||
hio_t* hrecv (hloop_t* loop, int connfd, void* buf, size_t len, hread_cb read_cb);
|
||||
// 发送
|
||||
// hio_get -> hio_setcb_write -> hio_write
|
||||
hio_t* hsend (hloop_t* loop, int connfd, const void* buf, size_t len, hwrite_cb write_cb DEFAULT(NULL));
|
||||
|
||||
// udp
|
||||
// 设置IO类型
|
||||
void hio_set_type(hio_t* io, hio_type_e type);
|
||||
// 设置本地地址
|
||||
void hio_set_localaddr(hio_t* io, struct sockaddr* addr, int addrlen);
|
||||
// 设置对端地址
|
||||
void hio_set_peeraddr (hio_t* io, struct sockaddr* addr, int addrlen);
|
||||
// 接收
|
||||
// hio_get -> hio_set_readbuf -> hio_setcb_read -> hio_read
|
||||
hio_t* hrecvfrom (hloop_t* loop, int sockfd, void* buf, size_t len, hread_cb read_cb);
|
||||
// 发送
|
||||
// hio_get -> hio_setcb_write -> hio_write
|
||||
hio_t* hsendto (hloop_t* loop, int sockfd, const void* buf, size_t len, hwrite_cb write_cb DEFAULT(NULL));
|
||||
|
||||
//-----------------顶层的接口---------------------------------------------
|
||||
// 创建socket套接字,返回IO对象
|
||||
// @hio_create_socket: socket -> bind -> listen
|
||||
// sockaddr_set_ipport -> socket -> hio_get(loop, sockfd) ->
|
||||
// side == HIO_SERVER_SIDE ? bind ->
|
||||
// type & HIO_TYPE_SOCK_STREAM ? listen ->
|
||||
hio_t* hio_create_socket(hloop_t* loop, const char* host, int port,
|
||||
hio_type_e type DEFAULT(HIO_TYPE_TCP),
|
||||
hio_side_e side DEFAULT(HIO_SERVER_SIDE));
|
||||
|
||||
// @tcp_server: hio_create_socket(loop, host, port, HIO_TYPE_TCP, HIO_SERVER_SIDE) -> hio_setcb_accept -> hio_accept
|
||||
// 创建TCP服务,示例代码见 examples/tcp_echo_server.c
|
||||
hio_t* hloop_create_tcp_server (hloop_t* loop, const char* host, int port, haccept_cb accept_cb);
|
||||
|
||||
// @tcp_client: hio_create_socket(loop, host, port, HIO_TYPE_TCP, HIO_CLIENT_SIDE) -> hio_setcb_connect -> hio_setcb_close -> hio_connect
|
||||
// 创建TCP客户端,示例代码见 examples/nc.c
|
||||
hio_t* hloop_create_tcp_client (hloop_t* loop, const char* host, int port, hconnect_cb connect_cb, hclose_cb close_cb);
|
||||
|
||||
// @ssl_server: hio_create_socket(loop, host, port, HIO_TYPE_SSL, HIO_SERVER_SIDE) -> hio_setcb_accept -> hio_accept
|
||||
// 创建SSL服务端,示例代码见 examples/tcp_echo_server.c => #define TEST_SSL 1
|
||||
hio_t* hloop_create_ssl_server (hloop_t* loop, const char* host, int port, haccept_cb accept_cb);
|
||||
|
||||
// @ssl_client: hio_create_socket(loop, host, port, HIO_TYPE_SSL, HIO_CLIENT_SIDE) -> hio_setcb_connect -> hio_setcb_close -> hio_connect
|
||||
// 创建SSL客户端,示例代码见 examples/nc.c => #define TEST_SSL 1
|
||||
hio_t* hloop_create_ssl_client (hloop_t* loop, const char* host, int port, hconnect_cb connect_cb, hclose_cb close_cb);
|
||||
|
||||
// @udp_server: hio_create_socket(loop, host, port, HIO_TYPE_UDP, HIO_SERVER_SIDE)
|
||||
// 创建UDP服务端,示例代码见 examples/udp_echo_server.c
|
||||
hio_t* hloop_create_udp_server (hloop_t* loop, const char* host, int port);
|
||||
|
||||
// @udp_server: hio_create_socket(loop, host, port, HIO_TYPE_UDP, HIO_CLIENT_SIDE)
|
||||
// 创建UDP客户端,示例代码见 examples/nc.c
|
||||
hio_t* hloop_create_udp_client (hloop_t* loop, const char* host, int port);
|
||||
|
||||
//-----------------pipe---------------------------------------------
|
||||
// 创建pipe,示例代码见 examples/pipe_test.c
|
||||
int hio_create_pipe(hloop_t* loop, hio_t* pipeio[2]);
|
||||
|
||||
//-----------------转发---------------------------------------------
|
||||
// hio_read(io)
|
||||
// hio_read(io->upstream_io)
|
||||
void hio_read_upstream(hio_t* io);
|
||||
// on_write(io) -> hio_write_is_complete(io) -> hio_read(io->upstream_io)
|
||||
void hio_read_upstream_on_write_complete(hio_t* io, const void* buf, int writebytes);
|
||||
// hio_write(io->upstream_io, buf, bytes)
|
||||
void hio_write_upstream(hio_t* io, void* buf, int bytes);
|
||||
// hio_close(io->upstream_io)
|
||||
void hio_close_upstream(hio_t* io);
|
||||
|
||||
// io1->upstream_io = io2;
|
||||
// io2->upstream_io = io1;
|
||||
// 建立转发,示例代码见 examples/socks5_proxy_server.c
|
||||
void hio_setup_upstream(hio_t* io1, hio_t* io2);
|
||||
|
||||
// @return io->upstream_io
|
||||
hio_t* hio_get_upstream(hio_t* io);
|
||||
|
||||
// @tcp_upstream: hio_create_socket -> hio_setup_upstream -> hio_connect -> on_connect -> hio_read_upstream
|
||||
// @return upstream_io
|
||||
// 建立TCP转发,示例代码见 examples/tcp_proxy_server.c
|
||||
hio_t* hio_setup_tcp_upstream(hio_t* io, const char* host, int port, int ssl DEFAULT(0));
|
||||
// 建立SSL转发
|
||||
#define hio_setup_ssl_upstream(io, host, port) hio_setup_tcp_upstream(io, host, port, 1)
|
||||
|
||||
// @udp_upstream: hio_create_socket -> hio_setup_upstream -> hio_read_upstream
|
||||
// @return upstream_io
|
||||
// 建立UDP转发,示例代码见 examples/udp_proxy_server.c
|
||||
hio_t* hio_setup_udp_upstream(hio_t* io, const char* host, int port);
|
||||
|
||||
//-----------------拆包---------------------------------------------
|
||||
// 拆包模式
|
||||
typedef enum {
|
||||
UNPACK_MODE_NONE = 0,
|
||||
UNPACK_BY_FIXED_LENGTH = 1, // 固定长度拆包,不建议
|
||||
UNPACK_BY_DELIMITER = 2, // 根据分隔符拆包,适用于文本协议
|
||||
UNPACK_BY_LENGTH_FIELD = 3, // 根据头部长度字段拆包,适用于二进制协议
|
||||
} unpack_mode_e;
|
||||
|
||||
// 拆包设置
|
||||
typedef struct unpack_setting_s {
|
||||
unpack_mode_e mode; // 拆包模式
|
||||
unsigned int package_max_length; // 最大的包长
|
||||
union {
|
||||
// UNPACK_BY_FIXED_LENGTH: 固定长度拆包设置
|
||||
struct {
|
||||
unsigned int fixed_length; // 固定长度
|
||||
};
|
||||
// UNPACK_BY_DELIMITER: 分隔符拆包设置
|
||||
struct {
|
||||
unsigned char delimiter[PACKAGE_MAX_DELIMITER_BYTES]; // 分隔符
|
||||
unsigned short delimiter_bytes; // 分隔符所占字节数
|
||||
};
|
||||
/*
|
||||
* UNPACK_BY_LENGTH_FIELD: 头部长度字段拆包设置
|
||||
*
|
||||
* 包长 = 头部长度 + 数据长度 + 调整长度
|
||||
* package_len = head_len + body_len + length_adjustment
|
||||
*
|
||||
* if (length_field_coding == ENCODE_BY_VARINT) head_len = body_offset + varint_bytes - length_field_bytes;
|
||||
* else head_len = body_offset;
|
||||
*
|
||||
* 注意:头部长度字段的值仅代表数据长度,不包括头部本身长度,
|
||||
* 如果你的头部长度字段代表总包长,那么应该将length_adjustment设置为负的头部长度
|
||||
* length_field stores body length, exclude head length,
|
||||
* if length_field = head_len + body_len, then length_adjustment should be set to -head_len.
|
||||
*
|
||||
*/
|
||||
struct {
|
||||
unsigned short body_offset; // 到数据的偏移,通常等于头部长度
|
||||
unsigned short length_field_offset; // 长度字段偏移
|
||||
unsigned short length_field_bytes; // 长度字段所占字节数
|
||||
short length_adjustment; // 调整长度
|
||||
unpack_coding_e length_field_coding; // 长度字段编码方式
|
||||
};
|
||||
};
|
||||
} unpack_setting_t;
|
||||
|
||||
/*
|
||||
* 拆包示例代码见 examples/jsonrpc examples/protorpc
|
||||
*
|
||||
* 注意:多个IO对象的unpack_setting_t可能是一样的,所有hio_t里仅保存了unpack_setting_t的指针,
|
||||
* unpack_setting_t的生命周期应该被调用者所保证,不应该使用局部变量。
|
||||
*/
|
||||
|
||||
// 设置拆包
|
||||
void hio_set_unpack(hio_t* io, unpack_setting_t* setting);
|
||||
// 取消拆包设置
|
||||
void hio_unset_unpack(hio_t* io);
|
||||
|
||||
// 拆包设置示例:
|
||||
/*
|
||||
|
||||
// FTP协议通过\r\n分割符拆包
|
||||
unpack_setting_t ftp_unpack_setting;
|
||||
memset(&ftp_unpack_setting, 0, sizeof(unpack_setting_t));
|
||||
ftp_unpack_setting.package_max_length = DEFAULT_PACKAGE_MAX_LENGTH;
|
||||
ftp_unpack_setting.mode = UNPACK_BY_DELIMITER;
|
||||
ftp_unpack_setting.delimiter[0] = '\r';
|
||||
ftp_unpack_setting.delimiter[1] = '\n';
|
||||
ftp_unpack_setting.delimiter_bytes = 2;
|
||||
|
||||
// MQTT协议通过头部长度字段拆包,头部长度字段使用了varint编码
|
||||
unpack_setting_t mqtt_unpack_setting = {
|
||||
.mode = UNPACK_BY_LENGTH_FIELD,
|
||||
.package_max_length = DEFAULT_PACKAGE_MAX_LENGTH,
|
||||
.body_offset = 2,
|
||||
.length_field_offset = 1,
|
||||
.length_field_bytes = 1,
|
||||
.length_field_coding = ENCODE_BY_VARINT,
|
||||
};
|
||||
|
||||
*/
|
||||
|
||||
//-----------------重连----------------------------------------
|
||||
// 重连设置
|
||||
typedef struct reconn_setting_s {
|
||||
uint32_t min_delay; // ms 重连最小延时
|
||||
uint32_t max_delay; // ms 重连最大延时
|
||||
uint32_t cur_delay; // ms 当前延时
|
||||
/*
|
||||
* @delay_policy: 延时策略
|
||||
* 0: fixed 固定延时
|
||||
* min_delay=3s => 3,3,3...
|
||||
* 1: linear 线性增长延时
|
||||
* min_delay=3s max_delay=10s => 3,6,9,10,10...
|
||||
* other: exponential 指数增长延时
|
||||
* min_delay=3s max_delay=60s delay_policy=2 => 3,6,12,24,48,60,60...
|
||||
*/
|
||||
uint32_t delay_policy; // 延时策略
|
||||
uint32_t max_retry_cnt; // 最大重试次数
|
||||
uint32_t cur_retry_cnt; // 当前重试次数
|
||||
} reconn_setting_t;
|
||||
|
||||
// 重连设置初始化
|
||||
void reconn_setting_init(reconn_setting_t* reconn);
|
||||
|
||||
// 重连设置重置
|
||||
void reconn_setting_reset(reconn_setting_t* reconn);
|
||||
|
||||
// 增加重试次数并判断是否未超过最大重试次数
|
||||
bool reconn_setting_can_retry(reconn_setting_t* reconn);
|
||||
|
||||
// 计算当前重连延时
|
||||
uint32_t reconn_setting_calc_delay(reconn_setting_t* reconn);
|
||||
|
||||
//-----------------负载均衡-------------------------------------
|
||||
// 负载均衡策略枚举
|
||||
typedef enum {
|
||||
LB_RoundRobin, // 轮询
|
||||
LB_Random, // 随机
|
||||
LB_LeastConnections,// 最少连接数
|
||||
LB_IpHash, // IP hash
|
||||
LB_UrlHash, // URL hash
|
||||
} load_balance_e;
|
||||
|
||||
//-----------------可靠UDP---------------------------------------------
|
||||
// 关闭可靠UDP
|
||||
int hio_close_rudp(hio_t* io, struct sockaddr* peeraddr DEFAULT(NULL));
|
||||
|
||||
// KCP设置
|
||||
typedef struct kcp_setting_s {
|
||||
// ikcp_create(conv, ...)
|
||||
unsigned int conv;
|
||||
// ikcp_nodelay(kcp, nodelay, interval, fastresend, nocwnd)
|
||||
int nodelay;
|
||||
int interval;
|
||||
int fastresend;
|
||||
int nocwnd;
|
||||
// ikcp_wndsize(kcp, sndwnd, rcvwnd)
|
||||
int sndwnd;
|
||||
int rcvwnd;
|
||||
// ikcp_setmtu(kcp, mtu)
|
||||
int mtu;
|
||||
// ikcp_update
|
||||
int update_interval;
|
||||
} kcp_setting_t;
|
||||
|
||||
// KCP 正常模式
|
||||
HV_INLINE void kcp_setting_init_with_normal_mode(kcp_setting_t* setting);
|
||||
|
||||
// KCP fast模式
|
||||
void kcp_setting_init_with_fast_mode(kcp_setting_t* setting);
|
||||
|
||||
// KCP fast2模式
|
||||
void kcp_setting_init_with_fast2_mode(kcp_setting_t* setting);
|
||||
|
||||
// KCP fast3模式
|
||||
void kcp_setting_init_with_fast3_mode(kcp_setting_t* setting);
|
||||
|
||||
// 设置KCP,示例代码见 examples/udp_echo_server.c => #define TEST_KCP 1
|
||||
int hio_set_kcp(hio_t* io, kcp_setting_t* setting DEFAULT(NULL));
|
||||
|
||||
```
|
||||
|
||||
示例代码:
|
||||
|
||||
- 事件循环: [examples/hloop_test.c](../../examples/hloop_test.c)
|
||||
- 定时器: [examples/htimer_test.c](../../examples/htimer_test.c)
|
||||
- TCP回显服务: [examples/tcp_echo_server.c](../../examples/tcp_echo_server.c)
|
||||
- TCP聊天服务: [examples/tcp_chat_server.c](../../examples/tcp_chat_server.c)
|
||||
- TCP代理服务: [examples/tcp_proxy_server.c](../../examples/tcp_proxy_server.c)
|
||||
- TCP客户端: [examples/tcp_client_test.c](../../examples/tcp_client_test.c)
|
||||
- UDP回显服务: [examples/udp_echo_server.c](../../examples/udp_echo_server.c)
|
||||
- UDP代理服务: [examples/udp_proxy_server.c](../../examples/udp_proxy_server.c)
|
||||
- 网络客户端: [examples/nc](../../examples/nc.c)
|
||||
- SOCKS5代理服务: [examples/socks5_proxy_server.c](../../examples/socks5_proxy_server.c)
|
||||
- HTTP服务: [examples/tinyhttpd.c](../../examples/tinyhttpd.c)
|
||||
- HTTP代理服务: [examples/tinyproxyd.c](../../examples/tinyproxyd.c)
|
||||
- jsonRPC示例: [examples/jsonrpc](../../examples/jsonrpc)
|
||||
- protobufRPC示例: [examples/protorpc](../../examples/protorpc)
|
||||
|
||||
多进程/多线程模式示例代码:
|
||||
|
||||
- 多accept进程模式: [examples/multi-thread/multi-acceptor-processes.c](../../examples/multi-thread/multi-acceptor-processes.c)
|
||||
- 多accept线程模式: [examples/multi-thread/multi-acceptor-threads.c](../../examples/multi-thread/multi-acceptor-threads.c)
|
||||
- 一个accept线程+多worker线程: [examples/multi-thread/one-acceptor-multi-workers.c](../../examples/multi-thread/one-acceptor-multi-workers.c)
|
||||
Reference in New Issue
Block a user