241 lines
6.5 KiB
Go
241 lines
6.5 KiB
Go
package api3th
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"github.com/cihub/seelog"
|
|
"github.com/google/go-querystring/query"
|
|
"io"
|
|
"mongo.games.com/game/common"
|
|
"net/http"
|
|
"strings"
|
|
"sync"
|
|
"sync/atomic"
|
|
"time"
|
|
)
|
|
|
|
const (
|
|
// 智能机器人接口
|
|
APITypeAI = 0
|
|
// 智能化运营接口
|
|
APITypeSmart = 1
|
|
)
|
|
|
|
type BaseConfig struct {
|
|
sync.Once
|
|
methods map[string]string
|
|
urlNames map[string]string
|
|
seqNo uint64 // 日志序号
|
|
IPAddr string
|
|
AuthKey string // 接口认证秘钥
|
|
TimeoutDuration time.Duration // 请求超时时长
|
|
Name string // 游戏名称
|
|
ApiType int // 接口类型
|
|
}
|
|
|
|
func (c *BaseConfig) LogName() string {
|
|
return fmt.Sprint(c.Name, "Logger")
|
|
}
|
|
|
|
func (c *BaseConfig) Log() seelog.LoggerInterface {
|
|
return common.GetLoggerInstanceByName(c.LogName())
|
|
}
|
|
|
|
func (c *BaseConfig) OrderNum() uint64 {
|
|
return atomic.AddUint64(&c.seqNo, 1)
|
|
}
|
|
|
|
func (c *BaseConfig) Register(method, name, urlName string) {
|
|
if method == "" {
|
|
method = "POST"
|
|
}
|
|
if _, ok := c.urlNames[name]; ok {
|
|
panic(fmt.Sprintf("api3th registered name:%s urlName:%s", name, urlName))
|
|
}
|
|
c.urlNames[name] = urlName
|
|
c.methods[name] = method
|
|
}
|
|
|
|
func (c *BaseConfig) Do(name string, req interface{}, args ...time.Duration) (resp []byte, err error) {
|
|
// 加载配置
|
|
c.Once.Do(func() {
|
|
|
|
c.AuthKey = common.CustomConfig.GetString(fmt.Sprintf("%sApiKey", c.Name))
|
|
c.TimeoutDuration = time.Duration(common.CustomConfig.GetInt(fmt.Sprintf("%sApi3thTimeout", c.Name))) * time.Second
|
|
})
|
|
|
|
timeout := time.Duration(-1)
|
|
if len(args) > 0 {
|
|
timeout = args[0]
|
|
}
|
|
|
|
url, ok := c.urlNames[name]
|
|
if !ok {
|
|
return nil, errors.New(fmt.Sprintf("api3th no register %s", name))
|
|
}
|
|
|
|
var code int
|
|
method := strings.ToUpper(c.methods[name])
|
|
switch method {
|
|
case "POST":
|
|
code, resp, err = c.Post(url, req, timeout)
|
|
case "POSTFORM":
|
|
code, resp, err = c.PostForm(url, req)
|
|
case "POSTFORMTIMEOUT":
|
|
code, resp, err = c.PostFormTimeOut(url, req, timeout)
|
|
default:
|
|
err = errors.New(fmt.Sprintf("api3th method error %s", c.methods[name]))
|
|
}
|
|
if code != http.StatusOK {
|
|
err = errors.New(fmt.Sprint("error code ", code))
|
|
}
|
|
return
|
|
}
|
|
|
|
func (c *BaseConfig) Post(url string, req interface{}, timeout time.Duration) (int, []byte, error) {
|
|
logger := c.Log()
|
|
data, err := json.Marshal(req)
|
|
if err != nil {
|
|
logger.Error("json.Marshal() error ", err)
|
|
return 0, nil, err
|
|
}
|
|
seqNo := c.OrderNum()
|
|
logger.Tracef("%s PostRequest[%d] Url %s Param: %s", c.Name, seqNo, fmt.Sprint(c.IPAddr, url), string(data))
|
|
r, err := http.NewRequest("POST", fmt.Sprint(c.IPAddr, url), bytes.NewBuffer(data))
|
|
if err != nil {
|
|
logger.Errorf("%s PostRequest[%d] http.NewRequest() error: %v", c.Name, seqNo, err)
|
|
return 0, nil, err
|
|
}
|
|
r.Header.Set("Content-Type", "application/json")
|
|
if c.AuthKey != "" {
|
|
r.Header.Set("Ocp-Apim-Subscription-Key", c.AuthKey)
|
|
}
|
|
cli := http.Client{}
|
|
if timeout >= 0 {
|
|
cli.Timeout = timeout
|
|
} else {
|
|
cli.Timeout = c.TimeoutDuration
|
|
}
|
|
resp, err := cli.Do(r)
|
|
if err != nil {
|
|
logger.Errorf("%s PostRequest[%d] httpClient.Do() error: %v", c.Name, seqNo, err)
|
|
return 0, nil, err
|
|
}
|
|
defer resp.Body.Close()
|
|
respBytes, err := io.ReadAll(resp.Body)
|
|
if err != nil {
|
|
logger.Errorf("%s PostRequest[%d] io.ReadAll() error: %v", c.Name, seqNo, err)
|
|
return 0, nil, err
|
|
}
|
|
|
|
logger.Tracef("%s PostRequest[%d] StatusCode=%d Body=%s", c.Name, seqNo, resp.StatusCode, string(respBytes))
|
|
return resp.StatusCode, respBytes, nil
|
|
}
|
|
|
|
func (c *BaseConfig) PostFormTimeOut(url string, req interface{}, timeout time.Duration) (int, []byte, error) {
|
|
logger := c.Log()
|
|
data, err := json.Marshal(req)
|
|
if err != nil {
|
|
logger.Error("json.Marshal() error ", err)
|
|
return 0, nil, err
|
|
}
|
|
seqNo := c.OrderNum()
|
|
logger.Tracef("%s PostRequest[%d] Url %s Param: %s", c.Name, seqNo, fmt.Sprint(c.IPAddr, url), string(data))
|
|
|
|
params, query_err := query.Values(req)
|
|
if query_err != nil {
|
|
logger.Errorf("(c *BaseConfig) PostForm query.Values %v", query_err)
|
|
return 0, nil, query_err
|
|
}
|
|
rp := strings.NewReader(params.Encode())
|
|
|
|
r, err := http.NewRequest("POST", fmt.Sprint(c.IPAddr, url), rp)
|
|
if err != nil {
|
|
logger.Errorf("%s PostRequest[%d] http.NewRequest() error: %v", c.Name, seqNo, err)
|
|
return 0, nil, err
|
|
}
|
|
r.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
|
if c.AuthKey != "" {
|
|
r.Header.Set("Ocp-Apim-Subscription-Key", c.AuthKey)
|
|
}
|
|
cli := http.Client{}
|
|
if timeout >= 0 {
|
|
cli.Timeout = timeout
|
|
} else {
|
|
cli.Timeout = c.TimeoutDuration
|
|
}
|
|
resp, err := cli.Do(r)
|
|
if err != nil {
|
|
//logger.Errorf("%s PostRequest[%d] httpClient.Do() error: %v", c.Name, seqNo, err)
|
|
return 0, nil, err
|
|
}
|
|
defer resp.Body.Close()
|
|
respBytes, err := io.ReadAll(resp.Body)
|
|
if err != nil {
|
|
logger.Errorf("%s PostRequest[%d] io.ReadAll() error: %v", c.Name, seqNo, err)
|
|
return 0, nil, err
|
|
}
|
|
|
|
logger.Tracef("%s PostRequest[%d] StatusCode=%d Body=%s", c.Name, seqNo, resp.StatusCode, string(respBytes))
|
|
return resp.StatusCode, respBytes, nil
|
|
}
|
|
|
|
func (c *BaseConfig) PostForm(url1 string, req interface{}) (int, []byte, error) {
|
|
logger := c.Log()
|
|
|
|
data, err := json.Marshal(req)
|
|
if err != nil {
|
|
logger.Error("json.Marshal() error ", err)
|
|
return 0, nil, err
|
|
}
|
|
c.Log().Info(fmt.Sprint(c.IPAddr, url1), string(data))
|
|
|
|
params, query_err := query.Values(req)
|
|
if query_err != nil {
|
|
logger.Errorf("(c *BaseConfig) PostForm query.Values %v", query_err)
|
|
return 0, nil, query_err
|
|
}
|
|
//c.Log().Info(fmt.Sprint(c.IPAddr, url1),params.Encode())
|
|
//fmt.Println(vals.Encode())
|
|
//
|
|
//params := req.(url.Values)
|
|
res, err := http.PostForm(fmt.Sprint(c.IPAddr, url1), params)
|
|
if err != nil {
|
|
logger.Errorf("(c *BaseConfig) PostForm http.PostForm %v", err)
|
|
return 0, nil, err
|
|
}
|
|
defer res.Body.Close()
|
|
body, err := io.ReadAll(res.Body)
|
|
if err != nil {
|
|
logger.Errorf("(c *BaseConfig) PostForm io.ReadAll %v", err)
|
|
return 0, nil, err
|
|
}
|
|
|
|
//println(url, " ret:", string(body[:]))
|
|
|
|
//result := make(map[string]interface{})
|
|
//json.Unmarshal(body, &result)
|
|
|
|
return http.StatusOK, body, err
|
|
}
|
|
|
|
func (c *BaseConfig) Switch() bool {
|
|
switch c.ApiType {
|
|
case 1: // 智能化运营
|
|
return common.CustomConfig.GetBool(fmt.Sprintf("Use%sSmartApi3th", c.Name))
|
|
default: // ai
|
|
return common.CustomConfig.GetBool(fmt.Sprintf("Use%sRobotApi3th", c.Name))
|
|
}
|
|
}
|
|
|
|
func NewBaseConfig(name string, apiType int) *BaseConfig {
|
|
ret := new(BaseConfig)
|
|
ret.methods = make(map[string]string)
|
|
ret.urlNames = make(map[string]string)
|
|
ret.Name = name
|
|
ret.ApiType = apiType
|
|
return ret
|
|
}
|