mirror of
https://github.com/CPunch/gopenfusion.git
synced 2024-11-14 12:00:05 +00:00
113 lines
2.5 KiB
Go
113 lines
2.5 KiB
Go
|
package redis
|
||
|
|
||
|
/*
|
||
|
used for state management between shard and login servers
|
||
|
*/
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"encoding/json"
|
||
|
"fmt"
|
||
|
"strconv"
|
||
|
|
||
|
"github.com/CPunch/gopenfusion/config"
|
||
|
|
||
|
"github.com/redis/go-redis/v9"
|
||
|
)
|
||
|
|
||
|
type RedisHandler struct {
|
||
|
client *redis.Client
|
||
|
ctx context.Context
|
||
|
}
|
||
|
|
||
|
type LoginMetadata struct {
|
||
|
FEKey []byte `json:",omitempty"`
|
||
|
PlayerID int32 `json:",omitempty"`
|
||
|
}
|
||
|
|
||
|
type ShardMetadata struct {
|
||
|
IP string
|
||
|
Port int
|
||
|
}
|
||
|
|
||
|
const (
|
||
|
SHARD_SET = "shards"
|
||
|
)
|
||
|
|
||
|
func OpenRedis(addr string) (*RedisHandler, error) {
|
||
|
client := redis.NewClient(&redis.Options{
|
||
|
Addr: addr,
|
||
|
CredentialsProvider: config.GetRedisCredentials(),
|
||
|
})
|
||
|
|
||
|
_, err := client.Ping(context.Background()).Result()
|
||
|
return &RedisHandler{client: client, ctx: context.Background()}, err
|
||
|
}
|
||
|
|
||
|
func (r *RedisHandler) Close() error {
|
||
|
return r.client.Close()
|
||
|
}
|
||
|
|
||
|
// we store login queues into redis with the name "loginMetadata_<serialKey>"
|
||
|
// set to expire after config.LOGIN_TIMEOUT duration. this way we can easily
|
||
|
// have a shared pool of active serial keys & player login data which any
|
||
|
// shard can pull from
|
||
|
|
||
|
func makeLoginMetadataKey(serialKey int64) string {
|
||
|
return fmt.Sprintf("loginMetadata_%s", strconv.Itoa(int(serialKey)))
|
||
|
}
|
||
|
|
||
|
func (r *RedisHandler) QueueLogin(serialKey int64, data LoginMetadata) error {
|
||
|
value, err := json.Marshal(data)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
// add to table
|
||
|
return r.client.Set(r.ctx, makeLoginMetadataKey(serialKey), value, config.LOGIN_TIMEOUT).Err()
|
||
|
}
|
||
|
|
||
|
func (r *RedisHandler) GetLogin(serialKey int64) (LoginMetadata, error) {
|
||
|
value, err := r.client.Get(r.ctx, makeLoginMetadataKey(serialKey)).Result()
|
||
|
if err != nil {
|
||
|
return LoginMetadata{}, err
|
||
|
}
|
||
|
|
||
|
var data LoginMetadata
|
||
|
if err := json.Unmarshal([]byte(value), &data); err != nil {
|
||
|
return LoginMetadata{}, err
|
||
|
}
|
||
|
|
||
|
return data, nil
|
||
|
}
|
||
|
|
||
|
func (r *RedisHandler) RemoveLogin(serialKey int64) error {
|
||
|
return r.client.Del(r.ctx, makeLoginMetadataKey(serialKey)).Err()
|
||
|
}
|
||
|
|
||
|
func (r *RedisHandler) RegisterShard(shard ShardMetadata) error {
|
||
|
value, err := json.Marshal(shard)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
return r.client.SAdd(r.ctx, SHARD_SET, value).Err()
|
||
|
}
|
||
|
|
||
|
func (r *RedisHandler) GetShards() []ShardMetadata {
|
||
|
shardData := r.client.SMembers(r.ctx, SHARD_SET).Val()
|
||
|
|
||
|
// unmarshal all shards
|
||
|
shards := make([]ShardMetadata, 0, len(shardData))
|
||
|
for _, data := range shardData {
|
||
|
var shard ShardMetadata
|
||
|
if err := json.Unmarshal([]byte(data), &shard); err != nil {
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
shards = append(shards, shard)
|
||
|
}
|
||
|
|
||
|
return shards
|
||
|
}
|