123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613 |
- //go:build windows
- package yu_hpsocket
- import (
- yu_proxy "gogs.qqck.cn/s/tools/proxy"
- yu_sys "gogs.qqck.cn/s/tools/sys"
- )
- // Client
- //
- // @Description: Client 系列组件底层实现
- type Client[T any] struct {
- hListener uintptr
- hClient uintptr
- SSL bool
- Extra any // 附加数据
- // exdata----------------------------------
- socket uintptr
- // 事件----------------------------------
- onPrepareConnect func(t *T, Sender, ConnID, socket uintptr) HR
- onConnect func(t *T, Sender, ConnID uintptr) HR
- onHandShake func(t *T, Sender, ConnID uintptr) HR
- onSend func(t *T, Sender, ConnID, Data uintptr, Length uintptr) HR
- onReceive func(t *T, Sender, ConnID, Data uintptr, Length uintptr) HR
- onClose func(t *T, Sender, ConnID uintptr, Operation SO, ErrorCode int) HR
- // 扩展----------------------------------------------------------------
- _RemoteAddress string
- _Port int
- proxy_info *yu_proxy.Info
- proxy_connect bool
- }
- // isValid
- //
- // @Description: 对象是否有效
- func (t *Client[T]) isValid() bool {
- return t.hListener != 0 && t.hClient != 0
- }
- // Start
- //
- // @Description: 启动通信组件(并指定【可选】绑定地址)
- // @param RemoteAddress 服务端地址
- // @param Port 服务端端口
- // @param AsyncConnect 是否采用异步 Connect
- // @param BindAddress 绑定地址(默认:nullptr,TcpClient/UdpClient -> 不执行绑定操作,UdpCast 绑定 -> 0.0.0.0)
- // @param LocalPort 本地端口(默认:0)
- // @return bool 是否启动成功
- func (t *Client[T]) Start(RemoteAddress string, Port int, AsyncConnect bool, BindAddress string, LocalPort int) bool {
- if !t.isValid() {
- return false
- }
- // -------------------------------------------------------------------------------关联必要事件
- if t.onPrepareConnect == nil {
- t.OnPrepareConnect(func(t *T, Sender, ConnID, socket uintptr) HR {
- return HR_IGNORE
- })
- }
- // -------------------------------------------------------------------------------关联必要事件------end
- if t.proxy_info.Host == "" {
- return HP_Client_StartWithBindAddressAndLocalPort.CallBool(t.hClient,
- yu_sys.S{yu_sys.Gbk, RemoteAddress}, Port,
- AsyncConnect,
- yu_sys.S{yu_sys.Gbk, BindAddress}, LocalPort,
- )
- }
- // -------------------------------------------------------------------------------判断代理是否有效
- if !t.proxy_info.IsValid() || t.proxy_info.IsTimeout() {
- return false
- }
- // -------------------------------------------------------------------------------关联必要事件
- if t.onConnect == nil {
- t.OnConnect(func(t *T, Sender, ConnID uintptr) HR {
- return HR_IGNORE
- })
- }
- // -------------------------------------------------------------------------------关联必要事件------end
- t._RemoteAddress, t._Port = RemoteAddress, Port
- return HP_Client_StartWithBindAddressAndLocalPort.CallBool(t.hClient,
- yu_sys.S{yu_sys.Gbk, t.proxy_info.Host}, t.proxy_info.Port,
- AsyncConnect,
- yu_sys.S{yu_sys.Gbk, BindAddress}, LocalPort,
- )
- }
- // Stop
- //
- // @Description: 关闭客户端通信组件,关闭完成后断开与服务端的连接并释放所有资源
- // @return bool 是否成功关闭
- func (t *Client[T]) Stop() bool {
- if !t.isValid() {
- return false
- }
- return HP_Client_Stop.CallBool(t.hClient)
- }
- // Wait
- //
- // @Description: 等待通信组件停止运行
- // @param Milliseconds 超时时间(毫秒,默认:-1,永不超时)
- // @return bool 超时返回 false
- func (t *Client[T]) Wait(Milliseconds int) bool {
- if !t.isValid() {
- return false
- }
- return HP_Client_Wait.CallBool(t.hClient, Milliseconds)
- }
- // Send
- //
- // @Description: 向服务端发送数据
- // @param buf 欲发送的数据
- // @return bool 是否发送成功
- func (t *Client[T]) Send(buf []byte) bool {
- if !t.isValid() {
- return false
- }
- if len(buf) == 0 {
- return true
- }
- return HP_Client_Send.CallBool(t.hClient, buf, len(buf))
- }
- // SendS
- //
- // @Description: 向服务端发送数据
- // @param buf 欲发送的数据
- // @return bool 是否发送成功
- func (t *Client[T]) SendS(buf string) bool {
- if !t.isValid() {
- return false
- }
- if len(buf) == 0 {
- return true
- }
- return HP_Client_Send.CallBool(t.hClient, buf, len(buf))
- }
- // IsSecure
- //
- // @Description: 检测是否为安全连接(SSL/HTTPS)
- func (t *Client[T]) IsSecure() bool {
- if !t.isValid() {
- return false
- }
- return HP_Client_IsSecure.CallBool(t.hClient)
- }
- // SetExtra
- //
- // @Description: 设置连接的附加数据
- func (t *Client[T]) SetExtra(extra uintptr) *Client[T] {
- if !t.isValid() {
- return t
- }
- HP_Client_SetExtra.Call(t.hClient, extra)
- return t
- }
- // GetExtra
- //
- // @Description: 获取连接的附加数据
- func (t *Client[T]) GetExtra() uintptr {
- if !t.isValid() {
- return 0
- }
- return HP_Client_GetExtra.CallUintptr(t.hClient)
- }
- // HasStarted
- //
- // @Description: 检查通信组件是否已启动
- func (t *Client[T]) HasStarted() bool {
- if !t.isValid() {
- return false
- }
- return HP_Client_HasStarted.CallBool(t.hClient)
- }
- // GetState
- //
- // @Description: 查看通信组件当前状态,SS_ 开头常量
- func (t *Client[T]) GetState() SS {
- if !t.isValid() {
- return SS_STOPPED
- }
- return SS(HP_Client_GetState.CallUintptr(t.hClient))
- }
- // GetLastError
- //
- // @Description: 获取最近一次失败操作的错误代码
- func (t *Client[T]) GetLastError() int {
- if !t.isValid() {
- return 0
- }
- return HP_Client_GetLastError.CallInt(t.hClient)
- }
- // GetLastErrorDesc
- //
- // @Description: 获取最近一次失败操作的错误描述
- func (t *Client[T]) GetLastErrorDesc() string {
- if !t.isValid() {
- return "Not Object"
- }
- return HP_Client_GetLastErrorDesc.CallGbkToUtf8(t.hClient)
- }
- // GetConnectionID
- //
- // @Description: 获取该组件对象的连接 ID
- func (t *Client[T]) GetConnectionID() uintptr {
- if !t.isValid() {
- return 0
- }
- return HP_Client_GetConnectionID.CallUintptr(t.hClient)
- }
- // GetLocalAddress
- //
- // @Description: 获取连接的本地绑定信息
- func (t *Client[T]) GetLocalAddress() (address string, port int) {
- if !t.isValid() {
- return
- }
- j_address_len := 128
- j_address := make([]byte, 64)
- if !HP_Client_GetLocalAddress.CallBool(t.hClient, j_address, &j_address_len, &port) {
- return
- }
- j_address_len -= 1 // 有结束符 {0}
- j_unicode_len := j_address_len * 2
- j_unicode := make([]byte, j_unicode_len)
- yu_sys.MultiByteToWideChar.Call(936, 0, j_address, j_address_len, j_unicode, j_unicode_len)
- j_utf8_size := j_unicode_len * 2
- j_utf8 := make([]byte, j_utf8_size)
- address = string(j_utf8[:yu_sys.WideCharToMultiByte.CallInt(65001, 0, j_unicode, j_address_len, j_utf8, j_utf8_size, 0, 0)])
- return
- }
- // GetRemoteHost
- //
- // @Description: 获取连接的远程主机信息
- func (t *Client[T]) GetRemoteHost() (address string, port int) {
- if !t.isValid() {
- return
- }
- j_address_len := 128
- j_address := make([]byte, 64)
- if !HP_Client_GetRemoteHost.CallBool(t.hClient, j_address, &j_address_len, &port) {
- return
- }
- j_address_len -= 1 // 有结束符 {0}
- j_unicode_len := j_address_len * 2
- j_unicode := make([]byte, j_unicode_len)
- yu_sys.MultiByteToWideChar.Call(936, 0, j_address, j_address_len, j_unicode, j_unicode_len)
- j_utf8_size := j_unicode_len * 2
- j_utf8 := make([]byte, j_utf8_size)
- address = string(j_utf8[:yu_sys.WideCharToMultiByte.CallInt(65001, 0, j_unicode, j_address_len, j_utf8, j_utf8_size, 0, 0)])
- return
- }
- // GetPendingDataLength
- //
- // @Description: 获取连接中未发出数据的长度
- func (t *Client[T]) GetPendingDataLength() (length int) {
- if !t.isValid() {
- return
- }
- HP_Client_GetPendingDataLength.Call(t.hClient, &length)
- return
- }
- // SetFreeBufferPoolSize
- //
- // @Description: 设置内存块缓存池大小(通常设置为 -> PUSH 模型:5 - 10;PULL 模型:10 - 20 )
- func (t *Client[T]) SetFreeBufferPoolSize(FreeBufferPoolSize int) *Client[T] {
- if !t.isValid() {
- return t
- }
- HP_Client_SetFreeBufferPoolSize.Call(t.hClient, FreeBufferPoolSize)
- return t
- }
- // SetFreeBufferPoolHold
- //
- // @Description: 设置内存块缓存池回收阀值(通常设置为内存块缓存池大小的 3 倍)
- func (t *Client[T]) SetFreeBufferPoolHold(FreeBufferPoolHold int) *Client[T] {
- if !t.isValid() {
- return t
- }
- HP_Client_SetFreeBufferPoolHold.Call(t.hClient, FreeBufferPoolHold)
- return t
- }
- // GetFreeBufferPoolSize
- //
- // @Description: 获取内存块缓存池大小
- func (t *Client[T]) GetFreeBufferPoolSize() int {
- if !t.isValid() {
- return 0
- }
- return HP_Client_GetFreeBufferPoolSize.CallInt(t.hClient)
- }
- // GetFreeBufferPoolHold
- //
- // @Description: 获取内存块缓存池回收阀值
- func (t *Client[T]) GetFreeBufferPoolHold() int {
- if !t.isValid() {
- return 0
- }
- return HP_Client_GetFreeBufferPoolHold.CallInt(t.hClient)
- }
- // SetupSSLContext
- //
- // @Description: 初始化通信组件 SSL环境参数,SSL环境参数必须在 SSL通信组件启动前完成初始化,否则启动失败
- // @param VerifyMode SSL_VM_ 开头常量,SSL验证模式
- // @param PemCertFile 证书文件
- // @param PemKeyFile 私钥文件
- // @param KeyPasswod 私钥密码(没有密码则为空)
- // @param CAPemCertFileOrPath CA 证书文件或目录(单向验证或客户端可选)
- func (t *Client[T]) SetupSSLContext(VerifyMode SSL_VM, PemCertFile, PemKeyFile, KeyPasswod, CAPemCertFileOrPath string) bool {
- if !t.isValid() {
- return false
- }
- return HP_SSLClient_SetupSSLContext.CallBool(t.hClient, uintptr(VerifyMode),
- yu_sys.S{yu_sys.Gbk, PemCertFile}, yu_sys.S{yu_sys.Gbk, PemKeyFile},
- yu_sys.S{yu_sys.Gbk, KeyPasswod}, yu_sys.S{yu_sys.Gbk, CAPemCertFileOrPath},
- )
- }
- // SetupSSLContextByMemory
- //
- // @Description: 初始化通信组件 SSL环境参数,SSL环境参数必须在 SSL通信组件启动前完成初始化,否则启动失败
- // @param VerifyMode SSL_VM_ 开头常量,SSL验证模式
- // @param PemCert 证书内容
- // @param PemKey 私钥内容
- // @param KeyPasswod 私钥密码(没有密码则为空)
- // @param CAPemCert CA 证书内容(单向验证可选)
- func (t *Client[T]) SetupSSLContextByMemory(VerifyMode SSL_VM, PemCert, PemKey, KeyPasswod, CAPemCert string) bool {
- if !t.isValid() {
- return false
- }
- return HP_SSLClient_SetupSSLContextByMemory.CallBool(t.hClient, uintptr(VerifyMode),
- yu_sys.S{yu_sys.Gbk, PemCert}, yu_sys.S{yu_sys.Gbk, PemKey},
- yu_sys.S{yu_sys.Gbk, KeyPasswod}, yu_sys.S{yu_sys.Gbk, CAPemCert},
- )
- }
- // CleanupSSLContext
- //
- // @Description: 清理通信组件 SSL运行环境,回收 SSL相关内存
- func (t *Client[T]) CleanupSSLContext() *Client[T] {
- if !t.isValid() {
- return t
- }
- HP_SSLClient_CleanupSSLContext.Call(t.hClient)
- return t
- }
- // StartSSLHandShake
- //
- // @Description: 启动 SSL握手,当通信组件设置为非自动握手时,需要调用本方法启动 SSL握手
- func (t *Client[T]) StartSSLHandShake() bool {
- if !t.isValid() {
- return false
- }
- return HP_SSLClient_StartSSLHandShake.CallBool(t.hClient)
- }
- // SetSSLAutoHandShake
- //
- // @Description: 设置通信组件握手方式(默认:true,自动握手)
- func (t *Client[T]) SetSSLAutoHandShake(AutoHandShake bool) *Client[T] {
- if !t.isValid() {
- return t
- }
- HP_SSLClient_SetSSLAutoHandShake.Call(t.hClient, AutoHandShake)
- return t
- }
- // IsSSLAutoHandShake
- //
- // @Description: 获取通信组件握手方式
- func (t *Client[T]) IsSSLAutoHandShake() bool {
- if !t.isValid() {
- return false
- }
- return HP_SSLClient_IsSSLAutoHandShake.CallBool(t.hClient)
- }
- // SetSSLCipherList
- //
- // @Description: 设置 SSL加密算法列表
- func (t *Client[T]) SetSSLCipherList(CipherList string) *Client[T] {
- if !t.isValid() {
- return t
- }
- HP_SSLClient_SetSSLCipherList.Call(t.hClient, yu_sys.S{yu_sys.Gbk, CipherList})
- return t
- }
- // GetSSLCipherList
- //
- // @Description: 获取 SSL加密算法列表
- func (t *Client[T]) GetSSLCipherList() string {
- if !t.isValid() {
- return ""
- }
- return HP_SSLClient_GetSSLCipherList.CallGbkToUtf8(t.hClient)
- }
- // GetSSLSessionInfo
- //
- // @Description: 获取指定类型的 SSLSession 信息(输出类型参考:SSL_SSI_)
- // @param enInfo SSL_SSI_ 开头常量
- func (t *Client[T]) GetSSLSessionInfo(enInfo SSL_SSI) (Info uintptr) {
- if !t.isValid() {
- return
- }
- HP_SSLClient_GetSSLSessionInfo.Call(t.hClient, uintptr(enInfo), &Info)
- return
- }
- // IsPauseReceive
- //
- // @Description: 获取连接的数据接收状态
- func (t *Client[T]) IsPauseReceive() (Paused bool) {
- if !t.isValid() {
- return
- }
- HP_Client_IsPauseReceive.Call(t.hClient, &Paused)
- return
- }
- // IsConnected
- //
- // @Description: 检测是否有效连接
- func (t *Client[T]) IsConnected() bool {
- if !t.isValid() {
- return false
- }
- return HP_Client_IsConnected.CallBool(t.hClient)
- }
- // SetReuseAddressPolicy
- //
- // @Description: 设置地址重用选项
- // @param enReusePolicy RAP_ 开头常量
- func (t *Client[T]) SetReuseAddressPolicy(ReusePolicy RAP) *Client[T] {
- if !t.isValid() {
- return t
- }
- HP_Client_SetReuseAddressPolicy.Call(t.hClient, uintptr(ReusePolicy))
- return t
- }
- // GetReuseAddressPolicy
- //
- // @Description: 获取地址重用选项 RAP_ 开头常量
- func (t *Client[T]) GetReuseAddressPolicy() RAP {
- if !t.isValid() {
- return RAP_NONE
- }
- return RAP(HP_Client_GetReuseAddressPolicy.CallUintptr(t.hClient))
- }
- // PauseReceive
- //
- // @Description: 暂停/恢复某个连接的数据接收工作
- func (t *Client[T]) PauseReceive(Paused bool) bool {
- if !t.isValid() {
- return false
- }
- return HP_Client_PauseReceive.CallBool(t.hClient, Paused)
- }
- // OnPrepareConnect
- //
- // @Description: 【可选】绑定准备连接事件
- // @param call->return HR_ 开头常量
- func (t *Client[T]) OnPrepareConnect(call func(t *T, Sender, ConnID, socket uintptr) HR) *Client[T] {
- if !t.isValid() {
- return t
- }
- if call == nil {
- HP_Set_FN_Client_OnPrepareConnect.Call(t.hListener, 0)
- } else {
- t.onPrepareConnect = call
- HP_Set_FN_Client_OnPrepareConnect.Call(t.hListener, client_callback_OnPrepareConnect_ptr)
- }
- return t
- }
- // OnConnect
- //
- // @Description: 【可选】绑定连接事件
- // @param call->return HR_ 开头常量
- func (t *Client[T]) OnConnect(call func(t *T, Sender, ConnID uintptr) HR) *Client[T] {
- if !t.isValid() {
- return t
- }
- if call == nil {
- HP_Set_FN_Client_OnConnect.Call(t.hListener, 0)
- } else {
- t.onConnect = call
- HP_Set_FN_Client_OnConnect.Call(t.hListener, client_callback_OnConnect_ptr)
- }
- return t
- }
- // OnHandShake
- //
- // @Description: 【可选】绑定握手事件
- // @param call->return HR_ 开头常量
- func (t *Client[T]) OnHandShake(call func(t *T, Sender, ConnID uintptr) HR) *Client[T] {
- if !t.isValid() {
- return t
- }
- if call == nil {
- HP_Set_FN_Client_OnHandShake.Call(t.hListener, 0)
- } else {
- t.onHandShake = call
- HP_Set_FN_Client_OnHandShake.Call(t.hListener, client_callback_OnHandShake_ptr)
- }
- return t
- }
- // OnSend
- //
- // @Description: 【可选】绑定发送事件
- // @param call->return HR_ 开头常量
- func (t *Client[T]) OnSend(call func(t *T, Sender, ConnID, Data uintptr, Length uintptr) HR) *Client[T] {
- if !t.isValid() {
- return t
- }
- if call == nil {
- HP_Set_FN_Client_OnSend.Call(t.hListener, 0)
- } else {
- t.onSend = call
- HP_Set_FN_Client_OnSend.Call(t.hListener, client_callback_OnSend_ptr)
- }
- return t
- }
- // OnReceive
- //
- // @Description: 【必选】绑定数据接收事件
- // @param call->return HR_ 开头常量
- func (t *Client[T]) OnReceive(call func(t *T, Sender, ConnID, Data uintptr, Length uintptr) HR) *Client[T] {
- if !t.isValid() {
- return t
- }
- if call == nil {
- HP_Set_FN_Client_OnReceive.Call(t.hListener, 0)
- } else {
- t.onReceive = call
- HP_Set_FN_Client_OnReceive.Call(t.hListener, client_callback_OnReceive_ptr)
- }
- return t
- }
- // OnClose
- //
- // @Description: 【必选】绑定断开事件
- // @param call->Operation 通过该参数标识是哪种操作导致的错误 SO_ 开头常量
- // @param call->return HR_ 开头常量
- func (t *Client[T]) OnClose(call func(t *T, Sender, ConnID uintptr, Operation SO, ErrorCode int) HR) *Client[T] {
- if !t.isValid() {
- return t
- }
- if call == nil {
- HP_Set_FN_Client_OnClose.Call(t.hListener, 0)
- } else {
- t.onClose = call
- HP_Set_FN_Client_OnClose.Call(t.hListener, client_callback_OnClose_ptr)
- }
- return t
- }
- // OnDefault
- //
- // @Description: 【可选】绑定所有【必选】事件
- func (t *Client[T]) OnDefault() *Client[T] {
- if !t.isValid() {
- return t
- }
- if t.onReceive == nil {
- t.OnReceive(func(t *T, Sender, ConnID, Data uintptr, Length uintptr) HR {
- return HR_OK
- })
- }
- if t.onClose == nil {
- t.OnClose(func(t *T, Sender, ConnID uintptr, Operation SO, ErrorCode int) HR {
- return HR_OK
- })
- }
- return t
- }
|