mirror of
https://github.com/CPunch/gopenfusion.git
synced 2024-11-14 03:50:05 +00:00
unknown
d7445e0f0f
- loginMetadata is passed to shards through redis now - shards announce they're alive via redis.AnnounceShard() which just populates a hashset keyed 'shards' - login servers grab the 'shards' hashset and randomly picks a shard to pass the player to (for now) - ./service shard && ./service login - Many new environment variables, check config/config.go for more info. or for a tl;dr just read the Dockerfile for the required ones - Shard and login services now run in different processes ! (and containers?? wooaaah)
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
|
|
}
|