f5/httpclimgr.go
aozhiwei 380443c39e 1
2024-04-18 20:39:12 +08:00

243 lines
4.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package f5
import (
"q5"
"encoding/json"
"sync/atomic"
)
/*
http的请求分为两种风格
go style: go风格回调的时候不会join主线程被回调方需要处理线程同步问题
js style: js风格回调时候会自动join主线程被回调方无需处理线程同步问题
*/
const (
GO_STYLE_REQUEST = 1
JS_STYLE_REQUEST = 2
NORMAL_CHANNEL = 1
QUICK_CHANNEL = 2
)
type HttpCliRequestHandle interface {
Cancel() bool
}
type httpCliRequestHandleImpl struct {
state int32 //-1: cancel 0:pending 1:started
cancelCount int32
}
type HttpCliResponse interface {
GetErr() error
GetJsonData() map[string]interface{}
GetRawData() string
IsTimeOut() bool
JsonParseOk() bool
}
type httpCliResponse struct {
err error
data map[string]interface{}
rawData string
isTimeOut bool
jsonParseOk bool
}
type httpCliMgr struct {
}
func (this *httpCliRequestHandleImpl) Cancel() bool {
ok := atomic.CompareAndSwapInt32(&this.state, 0, -1) ||
atomic.CompareAndSwapInt32(&this.state, -1, -1)
atomic.AddInt32(&this.cancelCount, 1)
return ok
}
func (this *httpCliMgr) init() {
_app.RegisterIMMsgHandle(
IM_HTTP_CLI_MGR_RESPONSE,
func(args q5.Args) {
cb := args[0].(func(HttpCliResponse))
rsp := args[1].(*httpCliResponse)
cb(rsp)
})
}
func (this *httpCliMgr) unInit() {
}
func (this *httpCliMgr) SendGoStyleRequest(
url string, params map[string]string,
cb func(HttpCliResponse)) HttpCliRequestHandle {
return this.internalSendRequest(
GO_STYLE_REQUEST,
NORMAL_CHANNEL,
url,
params,
nil,
cb)
}
func (this *httpCliMgr) SyncSendGoStyleRequest(
url string, params map[string]string,
cb func(HttpCliResponse)) {
chDone := make(chan bool)
this.internalSendRequest(
GO_STYLE_REQUEST,
NORMAL_CHANNEL,
url,
params,
nil,
func(rsp HttpCliResponse) {
cb(rsp)
chDone <- true
})
for {
select {
case <-chDone:
close(chDone)
return
}
}
}
func (this *httpCliMgr) SendJsStyleRequest(
url string, params map[string]string,
cb func(HttpCliResponse)) HttpCliRequestHandle {
return this.internalSendRequest(
JS_STYLE_REQUEST,
NORMAL_CHANNEL,
url,
params,
nil,
cb)
}
func (this *httpCliMgr) SendJsStyleJsonRspRequest(
url string, params map[string]string,
jsonRspObj interface{},
cb func(HttpCliResponse)) HttpCliRequestHandle {
if jsonRspObj == nil {
panic("SendJsStyleJsonRspRequest error jsonRspobj is nil")
}
return this.internalSendRequest(
JS_STYLE_REQUEST,
NORMAL_CHANNEL,
url,
params,
jsonRspObj,
cb)
}
func (this *httpCliMgr) SendQuickChannelGoStyleRequest(
url string, params map[string]string,
cb func(HttpCliResponse)) HttpCliRequestHandle {
return this.internalSendRequest(
GO_STYLE_REQUEST,
QUICK_CHANNEL,
url,
params,
nil,
cb)
}
func (this *httpCliMgr) SendQuickChannelJsStyleRequest(
url string, params map[string]string,
cb func(HttpCliResponse)) HttpCliRequestHandle {
return this.internalSendRequest(
JS_STYLE_REQUEST,
QUICK_CHANNEL,
url,
params,
nil,
cb)
}
func (this *httpCliMgr) SendQuickChannelJsStyleJsonRspRequest(
url string, params map[string]string,
jsonRspObj interface{},
cb func(HttpCliResponse)) HttpCliRequestHandle {
if jsonRspObj == nil {
panic("SendJsStyleJsonRspRequest error jsonRspobj is nil")
}
return this.internalSendRequest(
JS_STYLE_REQUEST,
QUICK_CHANNEL,
url,
params,
jsonRspObj,
cb)
}
func (this *httpCliMgr) internalSendRequest(
style int32, channel int32,
url string, params map[string]string,
jsonRspObj interface{},
cb func(HttpCliResponse)) HttpCliRequestHandle {
if !(style == GO_STYLE_REQUEST || style == JS_STYLE_REQUEST) {
panic("httpCliMgr sytel error")
}
if !(channel == NORMAL_CHANNEL || channel == QUICK_CHANNEL) {
panic("httpCliMgr channel error")
}
handle := &httpCliRequestHandleImpl{}
doFunc := func() {
if atomic.CompareAndSwapInt32(&handle.state, 0, 1) {
data, err := q5.HttpGet(url, params)
if cb == nil {
return
}
rsp := new(httpCliResponse)
rsp.init(data, err)
if rsp.GetErr() == nil && jsonRspObj != nil {
parseErr := json.Unmarshal([]byte(rsp.GetRawData()), jsonRspObj)
if parseErr == nil {
rsp.jsonParseOk = true
} else {
GetSysLog().Warning("f5.httpclimgr.internalSendRequest json error:%s url:%s params:%s",
parseErr,
url,
q5.EncodeJson(&params))
}
}
if style == GO_STYLE_REQUEST {
cb(rsp)
} else {
_app.AddIMMsg(IM_HTTP_CLI_MGR_RESPONSE, []interface{}{
cb,
rsp,
})
}
}
}
go doFunc()
return handle
}
func (this *httpCliResponse) init(data string, err error) {
this.err = err
this.rawData = data
}
func (this *httpCliResponse) GetErr() error {
return this.err
}
func (this *httpCliResponse) GetJsonData() map[string]interface{} {
return this.data
}
func (this *httpCliResponse) GetRawData() string {
return this.rawData
}
func (this *httpCliResponse) IsTimeOut() bool {
return this.isTimeOut
}
func (this *httpCliResponse) JsonParseOk() bool {
return this.jsonParseOk
}