218 lines
5.0 KiB
Go
218 lines
5.0 KiB
Go
package webapi
|
|
|
|
import (
|
|
"bytes"
|
|
"crypto/tls"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"net"
|
|
"net/http"
|
|
"net/url"
|
|
"strings"
|
|
"sync"
|
|
"sync/atomic"
|
|
"time"
|
|
|
|
"google.golang.org/protobuf/proto"
|
|
)
|
|
|
|
const DEFAULT_TIMEOUT = time.Duration(time.Second * 30)
|
|
|
|
var WebApiStats = new(sync.Map)
|
|
|
|
type ApiStats struct {
|
|
RunTimes int64 //执行次数
|
|
TotalRuningTime int64 //总执行时间
|
|
MaxRuningTime int64 //最长执行时间
|
|
TimeoutTimes int64 //执行超时次数
|
|
}
|
|
|
|
func DeviceOs(os string) string {
|
|
switch os {
|
|
case "ios":
|
|
return "2"
|
|
case "android":
|
|
return "1"
|
|
default:
|
|
return "0"
|
|
}
|
|
}
|
|
|
|
// API调用
|
|
// action 为需要调用的api, 例如 /api/Send/SendCode
|
|
// params 为需发送的参数
|
|
// protocol = https || http ||Post
|
|
func API_OP(url string, params url.Values) (map[string]interface{}, error) {
|
|
//res, err := http.PostForm("http://192.168.1.160:9090/api/Sms/SendCaptcha", params)
|
|
res, err := http.PostForm(Config.GameApiURL+url, params)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer res.Body.Close()
|
|
body, err := io.ReadAll(res.Body)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
//println(url, " ret:", string(body[:]))
|
|
|
|
result := make(map[string]interface{})
|
|
json.Unmarshal(body, &result)
|
|
|
|
return result, nil
|
|
}
|
|
|
|
// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// GET方式请求
|
|
func getRequest(appId, action string, params map[string]string, body proto.Message, protocol string, dura time.Duration) ([]byte, error) {
|
|
var client *http.Client
|
|
if strings.ToUpper(protocol) == "HTTPS" {
|
|
tr := &http.Transport{
|
|
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
|
}
|
|
client = &http.Client{Transport: tr}
|
|
} else {
|
|
client = &http.Client{}
|
|
}
|
|
data, err := proto.Marshal(body)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
callUrl := MakeURL(appId, action, params, data)
|
|
//println("callurl=", callUrl)
|
|
req, err := http.NewRequest("GET", callUrl, nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var stats *ApiStats
|
|
if v, exist := WebApiStats.Load(action); exist {
|
|
stats = v.(*ApiStats)
|
|
} else {
|
|
stats = &ApiStats{}
|
|
WebApiStats.Store(action, stats)
|
|
}
|
|
|
|
var isTimeout bool
|
|
start := time.Now()
|
|
defer func() {
|
|
ps := int64(time.Now().Sub(start) / time.Millisecond)
|
|
if stats != nil {
|
|
if isTimeout {
|
|
atomic.AddInt64(&stats.TimeoutTimes, 1)
|
|
}
|
|
atomic.AddInt64(&stats.RunTimes, 1)
|
|
atomic.AddInt64(&stats.TotalRuningTime, ps)
|
|
if atomic.LoadInt64(&stats.MaxRuningTime) < ps {
|
|
atomic.StoreInt64(&stats.MaxRuningTime, ps)
|
|
}
|
|
}
|
|
}()
|
|
|
|
//设置超时
|
|
client.Timeout = dura
|
|
req.Close = true
|
|
resp, err := client.Do(req)
|
|
if err != nil {
|
|
if uerr, ok := err.(net.Error); ok {
|
|
isTimeout = uerr.Timeout()
|
|
}
|
|
return nil, err
|
|
}
|
|
defer resp.Body.Close()
|
|
if resp.StatusCode == 200 {
|
|
body, err := io.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return body, err
|
|
}
|
|
println("callurl=", callUrl, "code=", resp.StatusCode)
|
|
return nil, fmt.Errorf("StatusCode:%d", resp.StatusCode)
|
|
}
|
|
|
|
// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// POST方式请求
|
|
func postRequest(appId, action string, params map[string]string, body proto.Message, protocol string, dura time.Duration) ([]byte, error) {
|
|
var client *http.Client
|
|
if strings.ToUpper(protocol) == "HTTPS" {
|
|
tr := &http.Transport{
|
|
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
|
}
|
|
client = &http.Client{Transport: tr}
|
|
} else {
|
|
client = &http.Client{}
|
|
}
|
|
|
|
data, err := proto.Marshal(body)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
callUrl := MakeURL(appId, action, params, data)
|
|
//println("callurl=", callUrl)
|
|
req, err := http.NewRequest("POST", callUrl, bytes.NewBuffer(data))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var stats *ApiStats
|
|
if v, exist := WebApiStats.Load(action); exist {
|
|
stats = v.(*ApiStats)
|
|
} else {
|
|
stats = &ApiStats{}
|
|
WebApiStats.Store(action, stats)
|
|
}
|
|
|
|
var isTimeout bool
|
|
start := time.Now()
|
|
defer func() {
|
|
ps := int64(time.Now().Sub(start) / time.Millisecond)
|
|
if stats != nil {
|
|
if isTimeout {
|
|
atomic.AddInt64(&stats.TimeoutTimes, 1)
|
|
}
|
|
atomic.AddInt64(&stats.RunTimes, 1)
|
|
atomic.AddInt64(&stats.TotalRuningTime, ps)
|
|
if atomic.LoadInt64(&stats.MaxRuningTime) < ps {
|
|
atomic.StoreInt64(&stats.MaxRuningTime, ps)
|
|
}
|
|
}
|
|
}()
|
|
|
|
//设置超时
|
|
client.Timeout = dura
|
|
req.Close = true
|
|
resp, err := client.Do(req)
|
|
if err != nil {
|
|
if uerr, ok := err.(net.Error); ok {
|
|
isTimeout = uerr.Timeout()
|
|
}
|
|
return nil, err
|
|
}
|
|
defer resp.Body.Close()
|
|
if resp.StatusCode == http.StatusOK {
|
|
body, err := io.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return body, err
|
|
}
|
|
println("callurl=", callUrl, "code=", resp.StatusCode)
|
|
return nil, fmt.Errorf("StatusCode:%d", resp.StatusCode)
|
|
}
|
|
|
|
func Stats() map[string]ApiStats {
|
|
stats := make(map[string]ApiStats)
|
|
WebApiStats.Range(func(k, v interface{}) bool {
|
|
if s, ok := v.(*ApiStats); ok {
|
|
ss := *s //计数可能不精准
|
|
stats[k.(string)] = ss
|
|
}
|
|
return true
|
|
})
|
|
return stats
|
|
}
|