game_sync/api3th/config.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
}