Apply .gitignore rules
This commit is contained in:
@@ -0,0 +1,860 @@
|
||||
package redisUtil
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
redisPoolObj_db *RedisPool
|
||||
)
|
||||
|
||||
func init() {
|
||||
redisPoolObj_db = NewRedisPool("testPool", "10.1.0.21:6379", "redis_pwd", 5, 500, 200, 10*time.Second, 5*time.Second)
|
||||
}
|
||||
|
||||
func TestExists(t *testing.T) {
|
||||
/*
|
||||
redis> SET db "redis"
|
||||
OK
|
||||
*/
|
||||
key := "db"
|
||||
value := "redis"
|
||||
successful, err := redisPoolObj_db.Set(key, value, "", 0, "")
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
if !successful {
|
||||
t.Errorf("Set the key:%s should be successful, but now it's not.", key)
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
redis> EXISTS db
|
||||
(integer) 1
|
||||
*/
|
||||
exist, err := redisPoolObj_db.Exists(key)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
if !exist {
|
||||
t.Errorf("Set the key:%s should exist, but now it doesn't.", key)
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
redis> DEL db
|
||||
(integer) 1
|
||||
*/
|
||||
expected := 1
|
||||
got, err := redisPoolObj_db.Del(key)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
if got != expected {
|
||||
t.Errorf("Expected to get %d, but now got %d", expected, got)
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
redis> EXISTS db
|
||||
(integer) 0
|
||||
*/
|
||||
exist, err = redisPoolObj_db.Exists(key)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
if exist {
|
||||
t.Errorf("Set the key:%s should not exist, but now it does.", key)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func TestType(t *testing.T) {
|
||||
deleteKeys := make([]string, 0, 8)
|
||||
defer func() {
|
||||
// Delete the test keys
|
||||
distinctKeyList := getDistinctKeyList(deleteKeys)
|
||||
count, err := redisPoolObj_string.Del(distinctKeyList...)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
if count != len(distinctKeyList) {
|
||||
t.Errorf("Expected to get %d, but now got %d", len(distinctKeyList), count)
|
||||
return
|
||||
}
|
||||
}()
|
||||
|
||||
/*
|
||||
# 字符串
|
||||
|
||||
redis> SET weather "sunny"
|
||||
OK
|
||||
|
||||
redis> TYPE weather
|
||||
string
|
||||
*/
|
||||
key := "weather"
|
||||
value := "sunny"
|
||||
|
||||
successful, err := redisPoolObj_db.Set(key, value, "", 0, "")
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
if !successful {
|
||||
t.Errorf("Set the key:%s should be successful, but now it's not.", key)
|
||||
return
|
||||
}
|
||||
|
||||
expected := "string"
|
||||
got, err := redisPoolObj_db.Type(key)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
if got != expected {
|
||||
t.Errorf("Expected to get %s, but now got %s", expected, got)
|
||||
return
|
||||
}
|
||||
|
||||
deleteKeys = append(deleteKeys, key)
|
||||
|
||||
/*
|
||||
# 列表
|
||||
|
||||
redis> LPUSH book_list "programming in scala"
|
||||
(integer) 1
|
||||
|
||||
redis> TYPE book_list
|
||||
list
|
||||
*/
|
||||
key = "book_list"
|
||||
value = "programming in scala"
|
||||
expected2 := 1
|
||||
got2, err := redisPoolObj_db.LPush(key, value)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
if got2 != expected2 {
|
||||
t.Errorf("Expected to get %d, but now got %d", expected2, got2)
|
||||
return
|
||||
}
|
||||
|
||||
expected = "list"
|
||||
got, err = redisPoolObj_db.Type(key)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
if got != expected {
|
||||
t.Errorf("Expected to get %s, but now got %s", expected, got)
|
||||
return
|
||||
}
|
||||
|
||||
deleteKeys = append(deleteKeys, key)
|
||||
|
||||
/*
|
||||
# 集合
|
||||
|
||||
redis> SADD pat "dog"
|
||||
(integer) 1
|
||||
|
||||
redis> TYPE pat
|
||||
set
|
||||
*/
|
||||
|
||||
key = "pat"
|
||||
value = "dog"
|
||||
expected3 := 1
|
||||
got3, err := redisPoolObj_db.SAdd(key, value)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
if got3 != expected3 {
|
||||
t.Errorf("Expected to get %d, but now got %d", expected3, got3)
|
||||
return
|
||||
}
|
||||
|
||||
expected = "set"
|
||||
got, err = redisPoolObj_db.Type(key)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
if got != expected {
|
||||
t.Errorf("Expected to get %s, but now got %s", expected, got)
|
||||
return
|
||||
}
|
||||
|
||||
deleteKeys = append(deleteKeys, key)
|
||||
}
|
||||
|
||||
func TestRename(t *testing.T) {
|
||||
deleteKeys := make([]string, 0, 8)
|
||||
defer func() {
|
||||
// Delete the test keys
|
||||
distinctKeyList := getDistinctKeyList(deleteKeys)
|
||||
count, err := redisPoolObj_string.Del(distinctKeyList...)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
if count != len(distinctKeyList) {
|
||||
t.Errorf("Expected to get %d, but now got %d", len(distinctKeyList), count)
|
||||
return
|
||||
}
|
||||
}()
|
||||
|
||||
/*
|
||||
# key 存在且 newkey 不存在
|
||||
|
||||
redis> SET message "hello world"
|
||||
OK
|
||||
|
||||
redis> RENAME message greeting
|
||||
OK
|
||||
|
||||
redis> EXISTS message # message 不复存在
|
||||
(integer) 0
|
||||
|
||||
redis> EXISTS greeting # greeting 取而代之
|
||||
(integer) 1
|
||||
*/
|
||||
key := "message"
|
||||
value := "hello world"
|
||||
expected := true
|
||||
got, err := redisPoolObj_db.Set(key, value, "", 0, "")
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
if got != expected {
|
||||
t.Errorf("Expected to get %t, but now got %t", expected, got)
|
||||
return
|
||||
}
|
||||
|
||||
newkey := "greeting"
|
||||
err = redisPoolObj_db.Rename(key, newkey)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
expected = false
|
||||
got, err = redisPoolObj_db.Exists(key)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
if got != expected {
|
||||
t.Errorf("Expected to get %t, but now got %t", expected, got)
|
||||
return
|
||||
}
|
||||
|
||||
expected = true
|
||||
got, err = redisPoolObj_db.Exists(newkey)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
if got != expected {
|
||||
t.Errorf("Expected to get %t, but now got %t", expected, got)
|
||||
return
|
||||
}
|
||||
|
||||
deleteKeys = append(deleteKeys, newkey)
|
||||
|
||||
/*
|
||||
# 当 key 不存在时,返回错误
|
||||
|
||||
redis> RENAME fake_key never_exists
|
||||
(error) ERR no such key
|
||||
*/
|
||||
key = "fake_key"
|
||||
newkey = "never_exists"
|
||||
err = redisPoolObj_db.Rename(key, newkey)
|
||||
if err == nil {
|
||||
t.Errorf("There should be one error, but now there isn't.")
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
# newkey 已存在时, RENAME 会覆盖旧 newkey
|
||||
|
||||
redis> SET pc "lenovo"
|
||||
OK
|
||||
|
||||
redis> SET personal_computer "dell"
|
||||
OK
|
||||
|
||||
redis> RENAME pc personal_computer
|
||||
OK
|
||||
|
||||
redis> GET pc
|
||||
(nil)
|
||||
|
||||
redis:1> GET personal_computer # 原来的值 dell 被覆盖了
|
||||
"lenovo"
|
||||
*/
|
||||
key = "pc"
|
||||
value = "lenovo"
|
||||
expected = true
|
||||
got, err = redisPoolObj_db.Set(key, value, "", 0, "")
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
if got != expected {
|
||||
t.Errorf("Expected to get %t, but now got %t", expected, got)
|
||||
return
|
||||
}
|
||||
|
||||
key = "personal_computer"
|
||||
value = "dell"
|
||||
expected = true
|
||||
got, err = redisPoolObj_db.Set(key, value, "", 0, "")
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
if got != expected {
|
||||
t.Errorf("Expected to get %t, but now got %t", expected, got)
|
||||
return
|
||||
}
|
||||
|
||||
key = "pc"
|
||||
newkey = "personal_computer"
|
||||
err = redisPoolObj_db.Rename(key, newkey)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
expected = false
|
||||
got, err = redisPoolObj_db.Exists(key)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
if got != expected {
|
||||
t.Errorf("Expected to get %t, but now got %t", expected, got)
|
||||
return
|
||||
}
|
||||
|
||||
expected = true
|
||||
got, err = redisPoolObj_db.Exists(newkey)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
if got != expected {
|
||||
t.Errorf("Expected to get %t, but now got %t", expected, got)
|
||||
return
|
||||
}
|
||||
|
||||
deleteKeys = append(deleteKeys, newkey)
|
||||
}
|
||||
|
||||
func TestRenameNX(t *testing.T) {
|
||||
deleteKeys := make([]string, 0, 8)
|
||||
defer func() {
|
||||
// Delete the test keys
|
||||
distinctKeyList := getDistinctKeyList(deleteKeys)
|
||||
count, err := redisPoolObj_string.Del(distinctKeyList...)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
if count != len(distinctKeyList) {
|
||||
t.Errorf("Expected to get %d, but now got %d", len(distinctKeyList), count)
|
||||
return
|
||||
}
|
||||
}()
|
||||
|
||||
/*
|
||||
# newkey 不存在,改名成功
|
||||
|
||||
redis> SET player "MPlyaer"
|
||||
OK
|
||||
|
||||
redis> EXISTS best_player
|
||||
(integer) 0
|
||||
|
||||
redis> RENAMENX player best_player
|
||||
(integer) 1
|
||||
*/
|
||||
key := "player"
|
||||
value := "MPlayer"
|
||||
expected := true
|
||||
got, err := redisPoolObj_db.Set(key, value, "", 0, "")
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
if got != expected {
|
||||
t.Errorf("Expected to get %t, but now got %t", expected, got)
|
||||
return
|
||||
}
|
||||
|
||||
newkey := "best_player"
|
||||
expected = false
|
||||
got, err = redisPoolObj_db.Exists(newkey)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
if got != expected {
|
||||
t.Errorf("Expected to get %t, but now got %t", expected, got)
|
||||
return
|
||||
}
|
||||
|
||||
expected = true
|
||||
got, err = redisPoolObj_db.RenameNX(key, newkey)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
if got != expected {
|
||||
t.Errorf("Expected to get %t, but now got %t", expected, got)
|
||||
return
|
||||
}
|
||||
|
||||
deleteKeys = append(deleteKeys, newkey)
|
||||
|
||||
/*
|
||||
# newkey存在时,失败
|
||||
|
||||
redis> SET animal "bear"
|
||||
OK
|
||||
|
||||
redis> SET favorite_animal "butterfly"
|
||||
OK
|
||||
|
||||
redis> RENAMENX animal favorite_animal
|
||||
(integer) 0
|
||||
|
||||
redis> get animal
|
||||
"bear"
|
||||
|
||||
redis> get favorite_animal
|
||||
"butterfly"
|
||||
*/
|
||||
key = "animal"
|
||||
value = "bear"
|
||||
expected = true
|
||||
got, err = redisPoolObj_db.Set(key, value, "", 0, "")
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
if got != expected {
|
||||
t.Errorf("Expected to get %t, but now got %t", expected, got)
|
||||
return
|
||||
}
|
||||
deleteKeys = append(deleteKeys, key)
|
||||
|
||||
key = "favorite_animal"
|
||||
value = "butterfly"
|
||||
expected = true
|
||||
got, err = redisPoolObj_db.Set(key, value, "", 0, "")
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
if got != expected {
|
||||
t.Errorf("Expected to get %t, but now got %t", expected, got)
|
||||
return
|
||||
}
|
||||
deleteKeys = append(deleteKeys, key)
|
||||
|
||||
expected = false
|
||||
got, err = redisPoolObj_db.RenameNX(key, newkey)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
if got != expected {
|
||||
t.Errorf("Expected to get %t, but now got %t", expected, got)
|
||||
return
|
||||
}
|
||||
|
||||
key2 := "animal"
|
||||
expected2 := "bear"
|
||||
got2_interface, exist2, err := redisPoolObj_db.Get(key2)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
if !exist2 {
|
||||
t.Errorf("The key:%s should exist, but now it doesn't.", key2)
|
||||
return
|
||||
}
|
||||
got2, err := redisPoolObj_db.String(got2_interface)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
if got2 != expected2 {
|
||||
t.Errorf("Expected to get %s, but now got %s", expected2, got2)
|
||||
return
|
||||
}
|
||||
|
||||
key3 := "animal"
|
||||
expected3 := "bear"
|
||||
got3_interface, exist3, err := redisPoolObj_db.Get(key3)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
if !exist3 {
|
||||
t.Errorf("The key:%s should exist, but now it doesn't.", key3)
|
||||
return
|
||||
}
|
||||
got3, err := redisPoolObj_db.String(got3_interface)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
if got3 != expected3 {
|
||||
t.Errorf("Expected to get %s, but now got %s", expected3, got3)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func TestDel(t *testing.T) {
|
||||
/*
|
||||
# 删除单个 key
|
||||
|
||||
redis> SET name huangz
|
||||
OK
|
||||
|
||||
redis> DEL name
|
||||
(integer) 1
|
||||
*/
|
||||
key := "name"
|
||||
value := "huangz"
|
||||
expected := true
|
||||
got, err := redisPoolObj_db.Set(key, value, "", 0, "")
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
if got != expected {
|
||||
t.Errorf("Expected to get %t, but now got %t", expected, got)
|
||||
return
|
||||
}
|
||||
|
||||
expected2 := 1
|
||||
got2, err := redisPoolObj_db.Del(key)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
if got2 != expected2 {
|
||||
t.Errorf("Expected to get %d, but now got %d", expected2, got2)
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
# 删除一个不存在的 key
|
||||
|
||||
redis> EXISTS phone
|
||||
(integer) 0
|
||||
|
||||
redis> DEL phone # 失败,没有 key 被删除
|
||||
(integer) 0
|
||||
*/
|
||||
key = "phone"
|
||||
expected = false
|
||||
got, err = redisPoolObj_db.Exists(key)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
if got != expected {
|
||||
t.Errorf("Expected to get %t, but now got %t", expected, got)
|
||||
return
|
||||
}
|
||||
|
||||
expected3 := 0
|
||||
got3, err := redisPoolObj_db.Del(key)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
if got3 != expected3 {
|
||||
t.Errorf("Expected to get %d, but now got %d", expected3, got3)
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
# 同时删除多个 key
|
||||
|
||||
redis> SET name "redis"
|
||||
OK
|
||||
|
||||
redis> SET type "key-value store"
|
||||
OK
|
||||
|
||||
redis> SET website "redis.com"
|
||||
OK
|
||||
|
||||
redis> DEL name type website
|
||||
(integer) 3
|
||||
*/
|
||||
key1 := "name"
|
||||
value1 := "redis"
|
||||
expected = true
|
||||
got, err = redisPoolObj_db.Set(key1, value1, "", 0, "")
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
if got != expected {
|
||||
t.Errorf("Expected to get %t, but now got %t", expected, got)
|
||||
return
|
||||
}
|
||||
key2 := "type"
|
||||
value2 := "key-value store"
|
||||
expected = true
|
||||
got, err = redisPoolObj_db.Set(key2, value2, "", 0, "")
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
if got != expected {
|
||||
t.Errorf("Expected to get %t, but now got %t", expected, got)
|
||||
return
|
||||
}
|
||||
key3 := "website"
|
||||
value3 := "redis.com"
|
||||
expected = true
|
||||
got, err = redisPoolObj_db.Set(key3, value3, "", 0, "")
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
if got != expected {
|
||||
t.Errorf("Expected to get %t, but now got %t", expected, got)
|
||||
return
|
||||
}
|
||||
|
||||
expected4 := 3
|
||||
got4, err := redisPoolObj_db.Del(key1, key2, key3)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
if got4 != expected4 {
|
||||
t.Errorf("Expected to get %d, but now got %d", expected4, got4)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func TestRandomKey(t *testing.T) {
|
||||
deleteKeys := make([]string, 0, 8)
|
||||
defer func() {
|
||||
// Delete the test keys
|
||||
distinctKeyList := getDistinctKeyList(deleteKeys)
|
||||
count, err := redisPoolObj_list.Del(distinctKeyList...)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
if count != len(distinctKeyList) {
|
||||
t.Errorf("Expected to get %d, but now got %d", len(distinctKeyList), count)
|
||||
return
|
||||
}
|
||||
}()
|
||||
|
||||
/*
|
||||
# 数据库为空
|
||||
|
||||
redis> RANDOMKEY
|
||||
(nil)
|
||||
*/
|
||||
expected := ""
|
||||
got, exist, err := redisPoolObj_db.RandomKey()
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
if exist {
|
||||
t.Errorf("RandomKey doesn't exist, but now it does.")
|
||||
return
|
||||
}
|
||||
if got != expected {
|
||||
t.Errorf("Expected to get %s, but now got %s", expected, got)
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
# 数据库不为空
|
||||
|
||||
redis> MSET fruit "apple" drink "beer" food "cookies" # 设置多个 key
|
||||
OK
|
||||
|
||||
redis> RANDOMKEY
|
||||
"fruit"
|
||||
|
||||
redis> RANDOMKEY
|
||||
"food"
|
||||
|
||||
redis> KEYS * # 查看数据库内所有key,证明 RANDOMKEY 并不删除 key
|
||||
1) "food"
|
||||
2) "drink"
|
||||
3) "fruit"
|
||||
*/
|
||||
key_value_map := make(map[string]interface{})
|
||||
key_value_map["fruit"] = "apple"
|
||||
key_value_map["drink"] = "beer"
|
||||
key_value_map["food"] = "cookies"
|
||||
err = redisPoolObj_db.MSet(key_value_map)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
got, exist, err = redisPoolObj_db.RandomKey()
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
if !exist {
|
||||
t.Errorf("RandomKey should exist, but now it doesn't.")
|
||||
return
|
||||
}
|
||||
if _, exist = key_value_map[got]; !exist {
|
||||
t.Errorf("RandomKey should exist, but now it doesn't.")
|
||||
return
|
||||
}
|
||||
|
||||
expected2 := make([]string, 0, len(key_value_map))
|
||||
for k := range key_value_map {
|
||||
expected2 = append(expected2, k)
|
||||
deleteKeys = append(deleteKeys, k)
|
||||
}
|
||||
got2, err := redisPoolObj_db.Keys("*")
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
if isTwoUnorderedSliceEqual(expected2, got2) == false {
|
||||
t.Errorf("Expected to get %v, but got %v\n", expected2, got2)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func TestDBSize(t *testing.T) {
|
||||
deleteKeys := make([]string, 0, 8)
|
||||
defer func() {
|
||||
// Delete the test keys
|
||||
distinctKeyList := getDistinctKeyList(deleteKeys)
|
||||
count, err := redisPoolObj_list.Del(distinctKeyList...)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
if count != len(distinctKeyList) {
|
||||
t.Errorf("Expected to get %d, but now got %d", len(distinctKeyList), count)
|
||||
return
|
||||
}
|
||||
}()
|
||||
|
||||
/*
|
||||
redis> DBSIZE
|
||||
(integer) 0
|
||||
|
||||
redis> SET new_key "hello_moto" # 增加一个 key 试试
|
||||
OK
|
||||
|
||||
redis> DBSIZE
|
||||
(integer) 1
|
||||
*/
|
||||
expected := 0
|
||||
got, err := redisPoolObj_db.DBSize()
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
if got != expected {
|
||||
t.Errorf("Expected to get %d, but now got %d", expected, got)
|
||||
return
|
||||
}
|
||||
|
||||
key := "new_key"
|
||||
value := "hello_moto"
|
||||
redisPoolObj_db.Set(key, value, "", 0, "")
|
||||
|
||||
deleteKeys = append(deleteKeys, key)
|
||||
|
||||
expected = 1
|
||||
got, err = redisPoolObj_db.DBSize()
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
if got != expected {
|
||||
t.Errorf("Expected to get %d, but now got %d", expected, got)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func TestKeys(t *testing.T) {
|
||||
deleteKeys := make([]string, 0, 8)
|
||||
defer func() {
|
||||
// Delete the test keys
|
||||
distinctKeyList := getDistinctKeyList(deleteKeys)
|
||||
count, err := redisPoolObj_list.Del(distinctKeyList...)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
if count != len(distinctKeyList) {
|
||||
t.Errorf("Expected to get %d, but now got %d", len(distinctKeyList), count)
|
||||
return
|
||||
}
|
||||
}()
|
||||
|
||||
/*
|
||||
redis> MSET one 1 two 2 three 3 four 4 # 一次设置 4 个 key
|
||||
OK
|
||||
*/
|
||||
key_value_map := make(map[string]interface{})
|
||||
key_value_map["one"] = "1"
|
||||
key_value_map["two"] = "2"
|
||||
key_value_map["three"] = "3"
|
||||
key_value_map["four"] = "4"
|
||||
err := redisPoolObj_db.MSet(key_value_map)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
for k := range key_value_map {
|
||||
deleteKeys = append(deleteKeys, k)
|
||||
}
|
||||
|
||||
/*
|
||||
redis> KEYS *o*
|
||||
1) "four"
|
||||
2) "two"
|
||||
3) "one"
|
||||
*/
|
||||
pattern := "*o*"
|
||||
expected := []string{"four", "two", "one"}
|
||||
got, err := redisPoolObj_db.Keys(pattern)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
if isTwoUnorderedSliceEqual(expected, got) == false {
|
||||
t.Errorf("Expected to get %v, but got %v\n", expected, got)
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
redis> KEYS t??
|
||||
1) "two"
|
||||
*/
|
||||
pattern = "t??"
|
||||
expected = []string{"two"}
|
||||
got, err = redisPoolObj_db.Keys(pattern)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
if isTwoUnorderedSliceEqual(expected, got) == false {
|
||||
t.Errorf("Expected to get %v, but got %v\n", expected, got)
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
redis> KEYS t[w]*
|
||||
1) "two"
|
||||
*/
|
||||
pattern = "t[w]*"
|
||||
expected = []string{"two"}
|
||||
got, err = redisPoolObj_db.Keys(pattern)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
if isTwoUnorderedSliceEqual(expected, got) == false {
|
||||
t.Errorf("Expected to get %v, but got %v\n", expected, got)
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
redis> KEYS * # 匹配数据库内所有 key
|
||||
1) "four"
|
||||
2) "three"
|
||||
3) "two"
|
||||
4) "one"
|
||||
*/
|
||||
pattern = "*"
|
||||
expected = []string{"two", "one", "three", "four"}
|
||||
got, err = redisPoolObj_db.Keys(pattern)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
if isTwoUnorderedSliceEqual(expected, got) == false {
|
||||
t.Errorf("Expected to get %v, but got %v\n", expected, got)
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,400 @@
|
||||
package httpServer
|
||||
|
||||
import (
|
||||
config "common/configsYaml"
|
||||
"common/resultStatus"
|
||||
"common/webServer"
|
||||
"goutil/logUtilPlus"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
// 供客户端访问的模块的后缀
|
||||
con_ModuleSuffix = "Module"
|
||||
|
||||
// 定义用于分隔模块名称和方法名称的分隔符
|
||||
con_DelimeterOfObjAndMethod = "_"
|
||||
)
|
||||
|
||||
var (
|
||||
// 定义存放所有方法映射的变量
|
||||
methodMap = make(map[string]*methodAndInOutTypes)
|
||||
|
||||
// 函数返回值类型
|
||||
responseType reflect.Type = reflect.TypeOf(new(webServer.ResponseObject))
|
||||
)
|
||||
|
||||
// getStructName
|
||||
// @description: 获取结构体类型的名称
|
||||
// parameter:
|
||||
// @structType: 结构体类型
|
||||
// return:
|
||||
// @string: 结构体类型的名称
|
||||
func getStructName(structType reflect.Type) string {
|
||||
reflectTypeStr := structType.String()
|
||||
reflectTypeArr := strings.Split(reflectTypeStr, ".")
|
||||
|
||||
return reflectTypeArr[len(reflectTypeArr)-1]
|
||||
}
|
||||
|
||||
// getFullModuleName
|
||||
// @description: 获取完整的模块名称
|
||||
// parameter:
|
||||
// @moduleName: 模块名称
|
||||
// return:
|
||||
// @string: 完整的模块名称
|
||||
func getFullModuleName(moduleName string) string {
|
||||
return moduleName + con_ModuleSuffix
|
||||
}
|
||||
|
||||
// getFullMethodName
|
||||
// @description: 获取完整的方法名称
|
||||
// parameter:
|
||||
// @structName: 结构体名称
|
||||
// @methodName: 方法名称
|
||||
// return:
|
||||
// @string: 完整的方法名称
|
||||
func getFullMethodName(structName, methodName string) string {
|
||||
return structName + con_DelimeterOfObjAndMethod + methodName
|
||||
}
|
||||
|
||||
// resolveMethodInOutParams
|
||||
// @description: 解析方法的输入输出参数
|
||||
// parameter:
|
||||
// @method: 方法对应的反射值
|
||||
// return:
|
||||
// @inTypes: 输入参数类型集合
|
||||
// @outTypes: 输出参数类型集合
|
||||
func resolveMethodInOutParams(method reflect.Value) (inTypes []reflect.Type, outTypes []reflect.Type) {
|
||||
methodType := method.Type()
|
||||
for i := 0; i < methodType.NumIn(); i++ {
|
||||
inTypes = append(inTypes, methodType.In(i))
|
||||
}
|
||||
|
||||
for i := 0; i < methodType.NumOut(); i++ {
|
||||
outTypes = append(outTypes, methodType.Out(i))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// RegisterFunction
|
||||
// @description: 将需要对客户端提供方法的对象进行注册
|
||||
// parameter:
|
||||
// @structObject: 对象
|
||||
// return:
|
||||
func RegisterFunction(structObject interface{}) {
|
||||
// 获取structObject对应的反射 Type 和 Value
|
||||
reflectValue := reflect.ValueOf(structObject)
|
||||
reflectType := reflect.TypeOf(structObject)
|
||||
|
||||
// 提取对象类型名称
|
||||
structName := getStructName(reflectType)
|
||||
|
||||
// 获取structObject中返回值为responseObject的方法
|
||||
for i := 0; i < reflectType.NumMethod(); i++ {
|
||||
// 获得方法名称
|
||||
methodName := reflectType.Method(i).Name
|
||||
|
||||
// 获得方法及其输入参数的类型列表
|
||||
method := reflectValue.MethodByName(methodName)
|
||||
inTypes, outTypes := resolveMethodInOutParams(method)
|
||||
|
||||
// 判断输出参数数量是否正确
|
||||
if len(outTypes) != 1 {
|
||||
continue
|
||||
}
|
||||
|
||||
// 判断返回值是否为responseObject
|
||||
if outTypes[0] != responseType {
|
||||
continue
|
||||
}
|
||||
|
||||
// 添加到列表中
|
||||
methodMap[getFullMethodName(structName, methodName)] = newmethodAndInOutTypes(method, inTypes, outTypes)
|
||||
}
|
||||
}
|
||||
|
||||
// CallFunction
|
||||
// @description: 调用方法
|
||||
// parameter:
|
||||
// @requestObj: 客户端对象
|
||||
// return:
|
||||
// @responseObj: 请求对象
|
||||
func CallFunction(requestObj *webServer.RequestObject) (responseObj *webServer.ResponseObject) {
|
||||
responseObj = webServer.GetInitResponseObj()
|
||||
|
||||
var methodAndInOutTypes *methodAndInOutTypes
|
||||
var ok bool
|
||||
|
||||
// 根据传入的ModuleName和MethodName找到对应的方法对象
|
||||
key := getFullMethodName(requestObj.ModuleName, requestObj.MethodName)
|
||||
if methodAndInOutTypes, ok = methodMap[key]; !ok {
|
||||
logUtilPlus.ErrorLog("找不到指定的方法:%s", key)
|
||||
responseObj.SetResultStatus(resultStatus.NotSpecificMethod)
|
||||
return
|
||||
}
|
||||
|
||||
// 判断参数数量是否相同
|
||||
inTypesLength := len(methodAndInOutTypes.InTypes)
|
||||
paramLength := len(requestObj.Parameters)
|
||||
if paramLength != inTypesLength {
|
||||
logUtilPlus.ErrorLog("传入的参数数量不符,本地方法%s的参数数量:%d,传入的参数数量为:%d", key, inTypesLength, paramLength)
|
||||
responseObj.SetResultStatus(resultStatus.ParamNotMatch)
|
||||
return
|
||||
}
|
||||
|
||||
// 构造参数
|
||||
in := make([]reflect.Value, inTypesLength)
|
||||
for i := 0; i < inTypesLength; i++ {
|
||||
inTypeItem := methodAndInOutTypes.InTypes[i]
|
||||
paramItem := requestObj.Parameters[i]
|
||||
|
||||
// 已支持类型:Client,Player(非基本类型)
|
||||
// 已支持类型:Bool,Int,Int8,Int16,Int32,Int64,Uint,Uint8,Uint16,Uint32,Uint64,Float32,Float64,String
|
||||
// 已支持类型:以及上面所列出类型的Slice类型
|
||||
// 未支持类型:Uintptr,Complex64,Complex128,Array,Chan,Func,Interface,Map,Ptr,Struct,UnsafePointer
|
||||
// 由于byte与int8同义,rune与int32同义,所以并不需要单独处理
|
||||
// 枚举参数的类型,并进行类型转换
|
||||
switch inTypeItem.Kind() {
|
||||
case reflect.Bool:
|
||||
if param_bool, ok := paramItem.(bool); ok {
|
||||
in[i] = reflect.ValueOf(param_bool)
|
||||
}
|
||||
case reflect.Int:
|
||||
if param_float64, ok := paramItem.(int); ok {
|
||||
in[i] = reflect.ValueOf(int(param_float64))
|
||||
}
|
||||
case reflect.Int8:
|
||||
if param_float64, ok := paramItem.(float64); ok {
|
||||
in[i] = reflect.ValueOf(int8(param_float64))
|
||||
}
|
||||
case reflect.Int16:
|
||||
if param_float64, ok := paramItem.(float64); ok {
|
||||
in[i] = reflect.ValueOf(int16(param_float64))
|
||||
}
|
||||
case reflect.Int32:
|
||||
if param_float64, ok := paramItem.(float64); ok {
|
||||
in[i] = reflect.ValueOf(int32(param_float64))
|
||||
}
|
||||
case reflect.Int64:
|
||||
if param_float64, ok := paramItem.(int64); ok {
|
||||
in[i] = reflect.ValueOf(int64(param_float64))
|
||||
} else if param_uint64, ok := paramItem.(uint64); ok {
|
||||
in[i] = reflect.ValueOf(int64(param_uint64))
|
||||
} else if param_string, ok := paramItem.(string); ok {
|
||||
|
||||
i64, err := strconv.ParseInt(param_string, 10, 64)
|
||||
|
||||
if err == nil {
|
||||
in[i] = reflect.ValueOf(i64)
|
||||
}
|
||||
}
|
||||
case reflect.Uint:
|
||||
if param_float64, ok := paramItem.(float64); ok {
|
||||
in[i] = reflect.ValueOf(uint(param_float64))
|
||||
}
|
||||
case reflect.Uint8:
|
||||
if param_float64, ok := paramItem.(uint8); ok {
|
||||
in[i] = reflect.ValueOf(uint8(param_float64))
|
||||
}
|
||||
case reflect.Uint16:
|
||||
if param_float64, ok := paramItem.(uint16); ok {
|
||||
in[i] = reflect.ValueOf(uint16(param_float64))
|
||||
}
|
||||
case reflect.Uint32:
|
||||
if param_float64, ok := paramItem.(float64); ok {
|
||||
in[i] = reflect.ValueOf(uint32(param_float64))
|
||||
}
|
||||
case reflect.Uint64:
|
||||
if param_float64, ok := paramItem.(float64); ok {
|
||||
in[i] = reflect.ValueOf(uint64(param_float64))
|
||||
}
|
||||
case reflect.Float32:
|
||||
if param_float64, ok := paramItem.(float64); ok {
|
||||
in[i] = reflect.ValueOf(float32(param_float64))
|
||||
}
|
||||
case reflect.Float64:
|
||||
if param_float64, ok := paramItem.(float64); ok {
|
||||
in[i] = reflect.ValueOf(param_float64)
|
||||
}
|
||||
case reflect.String:
|
||||
if param_string, ok := paramItem.(string); ok {
|
||||
in[i] = reflect.ValueOf(param_string)
|
||||
}
|
||||
case reflect.Slice:
|
||||
// 如果是Slice类型,则需要对其中的项再次进行类型判断及类型转换
|
||||
if param_interface, ok := paramItem.([]interface{}); ok {
|
||||
switch inTypeItem.String() {
|
||||
case "[]bool":
|
||||
params_inner := make([]bool, len(param_interface), len(param_interface))
|
||||
for i := 0; i < len(param_interface); i++ {
|
||||
if param_bool, ok := param_interface[i].(bool); ok {
|
||||
params_inner[i] = param_bool
|
||||
}
|
||||
}
|
||||
in[i] = reflect.ValueOf(params_inner)
|
||||
case "[]int":
|
||||
params_inner := make([]int, len(param_interface), len(param_interface))
|
||||
for i := 0; i < len(param_interface); i++ {
|
||||
if param_float64, ok := param_interface[i].(int); ok {
|
||||
params_inner[i] = int(param_float64)
|
||||
}
|
||||
}
|
||||
in[i] = reflect.ValueOf(params_inner)
|
||||
case "[]int8":
|
||||
params_inner := make([]int8, len(param_interface), len(param_interface))
|
||||
for i := 0; i < len(param_interface); i++ {
|
||||
if param_float64, ok := param_interface[i].(float64); ok {
|
||||
params_inner[i] = int8(param_float64)
|
||||
}
|
||||
}
|
||||
in[i] = reflect.ValueOf(params_inner)
|
||||
case "[]int16":
|
||||
params_inner := make([]int16, len(param_interface), len(param_interface))
|
||||
for i := 0; i < len(param_interface); i++ {
|
||||
if param_float64, ok := param_interface[i].(float64); ok {
|
||||
params_inner[i] = int16(param_float64)
|
||||
}
|
||||
}
|
||||
in[i] = reflect.ValueOf(params_inner)
|
||||
case "[]int32":
|
||||
params_inner := make([]int32, len(param_interface), len(param_interface))
|
||||
for i := 0; i < len(param_interface); i++ {
|
||||
param_float64, ok := param_interface[i].(int32)
|
||||
if ok {
|
||||
params_inner[i] = int32(param_float64)
|
||||
continue
|
||||
} else {
|
||||
param_int16, right := param_interface[i].(uint16)
|
||||
if right == true {
|
||||
params_inner[i] = int32(param_int16)
|
||||
}
|
||||
}
|
||||
}
|
||||
in[i] = reflect.ValueOf(params_inner)
|
||||
case "[]int64":
|
||||
params_inner := make([]int64, len(param_interface), len(param_interface))
|
||||
for i := 0; i < len(param_interface); i++ {
|
||||
if param_float64, ok := param_interface[i].(int64); ok {
|
||||
params_inner[i] = int64(param_float64)
|
||||
} else if param_uint64, ok := param_interface[i].(uint64); ok {
|
||||
params_inner[i] = int64(param_uint64)
|
||||
} else if param_string, ok := param_interface[i].(string); ok {
|
||||
|
||||
i64, err := strconv.ParseInt(param_string, 10, 64)
|
||||
|
||||
if err == nil {
|
||||
params_inner[i] = i64
|
||||
}
|
||||
}
|
||||
}
|
||||
in[i] = reflect.ValueOf(params_inner)
|
||||
case "[]uint":
|
||||
params_inner := make([]uint, len(param_interface), len(param_interface))
|
||||
for i := 0; i < len(param_interface); i++ {
|
||||
if param_float64, ok := param_interface[i].(uint); ok {
|
||||
params_inner[i] = uint(param_float64)
|
||||
}
|
||||
}
|
||||
in[i] = reflect.ValueOf(params_inner)
|
||||
// case "[]uint8": 特殊处理
|
||||
case "[]uint16":
|
||||
params_inner := make([]uint16, len(param_interface), len(param_interface))
|
||||
for i := 0; i < len(param_interface); i++ {
|
||||
if param_float64, ok := param_interface[i].(uint16); ok {
|
||||
params_inner[i] = uint16(param_float64)
|
||||
}
|
||||
}
|
||||
in[i] = reflect.ValueOf(params_inner)
|
||||
case "[]uint32":
|
||||
params_inner := make([]uint32, len(param_interface), len(param_interface))
|
||||
for i := 0; i < len(param_interface); i++ {
|
||||
if param_float64, ok := param_interface[i].(uint32); ok {
|
||||
params_inner[i] = uint32(param_float64)
|
||||
}
|
||||
}
|
||||
in[i] = reflect.ValueOf(params_inner)
|
||||
case "[]uint64":
|
||||
params_inner := make([]uint64, len(param_interface), len(param_interface))
|
||||
for i := 0; i < len(param_interface); i++ {
|
||||
if param_float64, ok := param_interface[i].(uint64); ok {
|
||||
params_inner[i] = uint64(param_float64)
|
||||
}
|
||||
}
|
||||
in[i] = reflect.ValueOf(params_inner)
|
||||
case "[]float32":
|
||||
params_inner := make([]float32, len(param_interface), len(param_interface))
|
||||
for i := 0; i < len(param_interface); i++ {
|
||||
if param_float64, ok := param_interface[i].(float64); ok {
|
||||
params_inner[i] = float32(param_float64)
|
||||
}
|
||||
}
|
||||
in[i] = reflect.ValueOf(params_inner)
|
||||
case "[]float64":
|
||||
params_inner := make([]float64, len(param_interface), len(param_interface))
|
||||
for i := 0; i < len(param_interface); i++ {
|
||||
if param_float64, ok := param_interface[i].(float64); ok {
|
||||
params_inner[i] = param_float64
|
||||
}
|
||||
}
|
||||
in[i] = reflect.ValueOf(params_inner)
|
||||
case "[]string":
|
||||
params_inner := make([]string, len(param_interface), len(param_interface))
|
||||
for i := 0; i < len(param_interface); i++ {
|
||||
if param_string, ok := param_interface[i].(string); ok {
|
||||
params_inner[i] = param_string
|
||||
}
|
||||
}
|
||||
in[i] = reflect.ValueOf(params_inner)
|
||||
}
|
||||
} else if inTypeItem.String() == "[]uint8" { // 由于[]uint8在传输过程中会被转化成字符串,所以单独处理;
|
||||
if param_string, ok := paramItem.(string); ok {
|
||||
param_uint8 := ([]uint8)(param_string)
|
||||
in[i] = reflect.ValueOf(param_uint8)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 判断是否有无效的参数(传入的参数类型和方法定义的类型不匹配导致没有赋值)
|
||||
for _, item := range in {
|
||||
if reflect.Value.IsValid(item) == false {
|
||||
logUtilPlus.ErrorLog("type:%v,value:%v.方法%s传入的参数%v无效", reflect.TypeOf(item), reflect.ValueOf(item), key, requestObj.Parameters)
|
||||
responseObj.SetResultStatus(resultStatus.ParamInValid)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 传入参数,调用方法
|
||||
if config.DEBUG {
|
||||
if requestObj.MethodName != "GetRefreshData" {
|
||||
logUtilPlus.DebugLog("Begin Call Func:module:%v, method:%v,inParams:%v\n\n", requestObj.ModuleName, requestObj.MethodName, in)
|
||||
}
|
||||
}
|
||||
|
||||
out := methodAndInOutTypes.Method.Call(in)
|
||||
|
||||
if config.DEBUG {
|
||||
if requestObj.MethodName != "GetRefreshData" {
|
||||
for i, v := range in {
|
||||
logUtilPlus.DebugLog("\nparams %v,%v\n", i, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 并输出结果到客户端(由于只有一个返回值,所以取out[0])
|
||||
if responseObj, ok = (&out[0]).Interface().(*webServer.ResponseObject); !ok {
|
||||
logUtilPlus.ErrorLog("返回值类型推断为ResponseObject 出错, tyep is :%v", reflect.TypeOf(out[0]))
|
||||
responseObj.SetResultStatus(resultStatus.ParamInValid)
|
||||
return
|
||||
}
|
||||
if config.DEBUG {
|
||||
if requestObj.MethodName != "GetRefreshData" {
|
||||
logUtilPlus.DebugLog("返回数据:code:%v, data:%v, mess:%v\n\n", responseObj.Code, responseObj.Value, responseObj.Message)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
此包提供通用的HTTP/HTTPS服务器功能;
|
||||
使用方法如下:
|
||||
1、初始化一个HttpServer/HttpsServer
|
||||
server := NewHttpServer(addr string, isCheckIP bool)
|
||||
或
|
||||
server := NewHttpsServer(addr, certFileName, keyFileName string, isCheckIP bool)
|
||||
其中参数说明如下:
|
||||
addr:服务器监听地址
|
||||
isCheckIP:是否需要验证客户端IP(此设置针对所有的请求,对于每个请求也可以单独设置;以此设置为优先)
|
||||
certFileName:证书文件的路径
|
||||
keyFileName:密钥文件的路径
|
||||
|
||||
2、设置server的属性
|
||||
在服务器运行过程中,会有一些默认的行为,如果想要改变默认行为,可以通过调用以下的方法进行设置
|
||||
|
||||
1)、设定Http Header信息
|
||||
SetHeader(header map[string]string)
|
||||
默认的Http Header为空;如果设定了Http Header,则在每次请求时,都会给ResponseWriter加上该header属性
|
||||
2)、设定HTTP请求方法
|
||||
SetMethod(method string)
|
||||
默认情况下,对请求的方法没有任何限制;如果设定了Method,则只允许该Method访问
|
||||
3)、设定当HTTP请求方法无效时,调用的处理器
|
||||
SetInvalidMethodHandler(handler func(*Context))
|
||||
默认情况下,如果请求方法与所设置的方法不一致时,会返回406错误;如果设置了此属性,则会调用此属性进行处理
|
||||
4)、设定默认页的处理器
|
||||
SetDefaultPageHandler(handler func(*Context))
|
||||
默认页指的是/, /favicon.ico这两个页面;默认情况下,仅仅是输出Welcome to home page.;如果需要针对做一些处理,可以设置此属性
|
||||
5)、设定未找到指定的回调时的处理器
|
||||
SetNotFoundPageHandler(handler func(*Context))
|
||||
当服务器找不到对应的地址的Handler时,会返回404错误。如果需要处理一些非固定的地址时,可以使用此方法;比如回调地址中包含AppId,所以导致地址可变
|
||||
6)、设定在Debug模式下是否需要验证IP地址
|
||||
SetIfCheckIPWhenDebug(value bool)
|
||||
默认情况下,在DEBUG模式时不验证IP;可以通过此属性改变此此行为
|
||||
7)、设定当IP无效时调用的处理器
|
||||
SetIPInvalidHandler(handler func(*Context))
|
||||
当需要验证IP并且IP无效时,默认情况下会返回401错误;如果设定了此属性,则可以改变该行为
|
||||
8)、设定当检测到参数无效时调用的处理器
|
||||
SetParamInvalidHandler(handler func(*Context))
|
||||
当检测到参数无效时,默认情况下会返回500错误;如果设置了此属性,则可以改变该行为
|
||||
9)、设定处理请求数据的处理器(例如压缩、解密等)
|
||||
SetRequestDataHandler(handler func(*Context, []byte) ([]byte, error))
|
||||
如果设定此属性,则在处理接收到的请求数据时,会调用此属性
|
||||
10)、设定处理响应数据的处理器(例如压缩、加密等)
|
||||
SetResponseDataHandler(handler func(*Context, []byte) ([]byte, error))
|
||||
如果设定此属性,则在处理返回给客户端的数据时,会调用此属性
|
||||
11)、设定请求执行时间的处理器
|
||||
SetExecuteTimeHandler(handler func(*Context))
|
||||
如果在请求结束后想要处理调用的时间,则需要设置此属性;例如请求时间过长则记录日志等
|
||||
|
||||
3、注册handler
|
||||
server.RegisterHandler(path string, handlerFuncObj handlerFunc, configObj *HandlerConfig)
|
||||
参数如下:
|
||||
// path:注册的访问路径
|
||||
// callback:回调方法
|
||||
// configObj:Handler配置对象
|
||||
例如:server.RegisterHandler("/get/notice", getNoticeConfig, &webServer.HandlerConfig{IsCheckIP: false, ParamNameList: []string{"appid"}})
|
||||
|
||||
4、启动对应的服务器
|
||||
server.Start(wg *sync.WaitGroup)
|
||||
|
||||
5、context中提供了很多实用的方法
|
||||
1)、GetRequestPath() string:获取请求路径(该路径不带参数)
|
||||
2)、GetRequestIP() string:获取请求的客户端的IP地址
|
||||
3)、GetExecuteSeconds() int64:获取请求执行的秒数。当然也可以通过获取StartTime, EndTime属性自己进行更高精度的处理
|
||||
4)、String() string:将context里面的内容进行格式化,主要用于记录日志
|
||||
5)、FormValue(key string) string:获取请求的参数值(包括GET/POST/PUT/DELETE等所有参数)
|
||||
6)、PostFormValue(key string) string:获取POST的参数值
|
||||
7)、GetFormValueData() typeUtil.MapData:获取所有参数的MapData类型(包括GET/POST/PUT/DELETE等所有参数)
|
||||
8)、GetPostFormValueData() typeUtil.MapData:获取POST参数的MapData类型
|
||||
9)、GetMultipartFormValueData() typeUtil.MapData:获取MultipartForm的MapData类型
|
||||
10)、GetRequestBytes() (result []byte, exists bool, err error):获取请求字节数据
|
||||
11)、GetRequestString() (result string, exists bool, err error):获取请求字符串数据
|
||||
12)、Unmarshal(obj interface{}) (exists bool, err error):反序列化为对象(JSON)
|
||||
13)、WriteString(result string):输出字符串给客户端
|
||||
14)、WriteJson(result interface{}):输出json数据给客户端
|
||||
15)、RedirectTo(url string):重定向到其它页面
|
||||
如果以上的方法不能满足需求,则可以调用以下的方法来获取原始的Request/ResponseWriter对象进行处理
|
||||
16)、GetRequest() *http.Request:获取请求对象
|
||||
17)、GetResponseWriter() http.ResponseWriter:获取响应对象
|
||||
*/
|
||||
package webServer
|
||||
@@ -0,0 +1,184 @@
|
||||
package managecenterModel
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"goutil/stringUtil"
|
||||
)
|
||||
|
||||
// 服务器组
|
||||
type ServerGroup struct {
|
||||
// 服务器组Id
|
||||
Id int32 `json:"GroupID"`
|
||||
|
||||
// 服务器组名称
|
||||
Name string `json:"GroupName"`
|
||||
|
||||
// 服务器组Url
|
||||
Url string `json:"GroupUrl"`
|
||||
|
||||
// 聊天服务器Url
|
||||
ChatServerUrl string `json:"ChatServerUrl"`
|
||||
|
||||
// 数据库连接配置
|
||||
DBConnectionConfig string `json:"DBConnectionConfig"`
|
||||
|
||||
// 服务器组状态(1:正常;2:维护)
|
||||
GroupState int32 `json:"GroupState"`
|
||||
|
||||
// 服务器组热度(1:正常;2:新服;3:推荐)
|
||||
GroupHeat int32 `json:"GroupHeat"`
|
||||
|
||||
// 服务器组负载(1:正常;2:火爆)
|
||||
GroupLoad int32 `json:"GroupLoad"`
|
||||
|
||||
// 服务器开服时间对应的Unix时间戳
|
||||
OpenTimeTick int64 `json:OpenTimeTick`
|
||||
|
||||
// 服务器组Ip(外网IP;内网IP;回调GS内网端口)
|
||||
Ip string `json:"GroupIp"`
|
||||
|
||||
// 正式服或测试服;1:正式服;2:测试服
|
||||
OfficialOrTest int32 `json:"OfficialOrTest"`
|
||||
|
||||
// 服务器组类型
|
||||
Type int32 `json:"GroupType"`
|
||||
|
||||
// 服务器组排序
|
||||
Order int32 `json:"GroupOrder"`
|
||||
|
||||
// 服务器组维护开始时间对应的时间戳
|
||||
MaintainBeginTimeTick int64 `json:MaintainBeginTimeTick`
|
||||
|
||||
// 维护持续分钟数
|
||||
MaintainMinutes int32 `json:"MaintainMinutes"`
|
||||
|
||||
// 维护信息
|
||||
MaintainMessage string `json:"MaintainMessage"`
|
||||
|
||||
// 游戏监听地址
|
||||
GameListenAddr string `json:"GameListenAddr"`
|
||||
|
||||
// 回调监听地址
|
||||
CallbackListenAddr string `json:"CallbackListenAddr"`
|
||||
|
||||
// 外网回调地址
|
||||
ExternalCallbackUrl string `json:"ExternalCallbackUrl"`
|
||||
|
||||
// 内网回调地址
|
||||
InternalCallbackUrl string `json:"InternalCallbackUrl"`
|
||||
|
||||
// 是否在主群组(机房)内
|
||||
IsInMainGroup bool `json:"IsInMainGroup"`
|
||||
|
||||
// 监控端口
|
||||
GopsPort string `json:"GopsPort"`
|
||||
}
|
||||
|
||||
// 排序方法(默认按照Id进行升序排序)
|
||||
// target:另一个服务器组对象
|
||||
// 是否是小于
|
||||
func (this *ServerGroup) SortByIdAsc(target *ServerGroup) bool {
|
||||
return this.Id < target.Id
|
||||
}
|
||||
|
||||
// 按照开服时间进行升序排序
|
||||
// target:另一个服务器组对象
|
||||
// 是否是小于
|
||||
func (this *ServerGroup) SortByOpenTimeAsc(target *ServerGroup) bool {
|
||||
return this.OpenTimeTick < target.OpenTimeTick
|
||||
}
|
||||
|
||||
// 获取数据库配置对象
|
||||
// 返回值:
|
||||
// 数据库配置对象
|
||||
// 错误对象
|
||||
func (this *ServerGroup) GetDBConfig() (*DBConnectionConfig, error) {
|
||||
var dbConfig *DBConnectionConfig
|
||||
if err := json.Unmarshal([]byte(this.DBConnectionConfig), &dbConfig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return dbConfig, nil
|
||||
}
|
||||
|
||||
// 获取ip列表
|
||||
// 返回值:
|
||||
// ip列表
|
||||
func (this *ServerGroup) GetIPList() []string {
|
||||
return stringUtil.Split(this.Ip, nil)
|
||||
}
|
||||
|
||||
// 服务器组是否开启
|
||||
// 返回值:
|
||||
// 是否开启
|
||||
func (this *ServerGroup) IsOpen() bool {
|
||||
return this.OpenTimeTick < time.Now().Unix()
|
||||
}
|
||||
|
||||
// 获取游戏服务器的回调地址
|
||||
// suffix:地址后缀
|
||||
// 返回值
|
||||
// 游戏服务器的回调地址
|
||||
func (this *ServerGroup) GetGSCallbackUrl(suffix string) string {
|
||||
// 如果是在主群组(机房)内,则使用内网地址,否则使用外网地址
|
||||
url := ""
|
||||
if this.IsInMainGroup {
|
||||
url = this.InternalCallbackUrl
|
||||
} else {
|
||||
url = this.ExternalCallbackUrl
|
||||
}
|
||||
|
||||
if url != "" {
|
||||
if strings.HasSuffix(url, "/") {
|
||||
return fmt.Sprintf("%s%s", url, suffix)
|
||||
} else {
|
||||
return fmt.Sprintf("%s/%s", url, suffix)
|
||||
}
|
||||
}
|
||||
|
||||
// 兼容旧的ManageCenter版本
|
||||
ipList := this.GetIPList()
|
||||
|
||||
// 外网IP;内网IP;回调GS内网端口;如果数量小于3,则直接使用配置的GroupUrl;否则使用第3个值
|
||||
if len(ipList) < 3 {
|
||||
if strings.HasSuffix(this.Url, "/") {
|
||||
return fmt.Sprintf("%s%s", this.Url, suffix)
|
||||
} else {
|
||||
return fmt.Sprintf("%s/%s", this.Url, suffix)
|
||||
}
|
||||
} else {
|
||||
return fmt.Sprintf("http://%s:%s/%s", ipList[1], ipList[2], suffix)
|
||||
}
|
||||
}
|
||||
|
||||
// 判断服务器组是否相同
|
||||
// target:目标服务器组
|
||||
// 是否相同
|
||||
func (this *ServerGroup) IsEqual(target *ServerGroup) bool {
|
||||
return this.Id == target.Id &&
|
||||
this.Name == target.Name &&
|
||||
this.Url == target.Url &&
|
||||
this.ChatServerUrl == target.ChatServerUrl &&
|
||||
this.DBConnectionConfig == target.DBConnectionConfig &&
|
||||
this.GroupState == target.GroupState &&
|
||||
this.GroupHeat == target.GroupHeat &&
|
||||
this.GroupLoad == target.GroupLoad &&
|
||||
this.OpenTimeTick == target.OpenTimeTick &&
|
||||
this.Ip == target.Ip &&
|
||||
this.OfficialOrTest == target.OfficialOrTest &&
|
||||
this.Type == target.Type &&
|
||||
this.Order == target.Order &&
|
||||
this.MaintainBeginTimeTick == target.MaintainBeginTimeTick &&
|
||||
this.MaintainMinutes == target.MaintainMinutes &&
|
||||
this.MaintainMessage == target.MaintainMessage &&
|
||||
this.GameListenAddr == target.GameListenAddr &&
|
||||
this.CallbackListenAddr == target.CallbackListenAddr &&
|
||||
this.ExternalCallbackUrl == target.ExternalCallbackUrl &&
|
||||
this.InternalCallbackUrl == target.InternalCallbackUrl &&
|
||||
this.IsInMainGroup == target.IsInMainGroup &&
|
||||
this.GopsPort == target.GopsPort
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package model
|
||||
|
||||
// 错误信息对象
|
||||
type ErrorInfo struct {
|
||||
// 错误码
|
||||
Code int `json:"code"`
|
||||
|
||||
// 错误提示信息
|
||||
Message string `json:"message"`
|
||||
|
||||
// 对应删除失败的消息句柄
|
||||
ReceiptHandle string `json:"receiptHandle"`
|
||||
}
|
||||
Reference in New Issue
Block a user