party로 그룹 변경
This commit is contained in:
129
core/tavern.go
129
core/tavern.go
@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
@ -18,19 +19,12 @@ import (
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/bsonrw"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultMaxMemory = 32 << 10 // 32 KB
|
||||
)
|
||||
|
||||
func writeBsonArr(w io.Writer, src []bson.M) error {
|
||||
return writeBsonDoc(w, bson.M{
|
||||
"r": src,
|
||||
})
|
||||
}
|
||||
|
||||
func writeBsonDoc[T any](w io.Writer, src T) error {
|
||||
rw, err := bsonrw.NewBSONValueWriter(w)
|
||||
if err != nil {
|
||||
@ -71,9 +65,9 @@ func readBsonDoc(r io.Reader, src any) error {
|
||||
type TavernConfig struct {
|
||||
gocommon.RegionStorageConfig `json:",inline"`
|
||||
|
||||
GroupTypes map[string]*groupConfig `json:"tavern_group_types"`
|
||||
MaingateApiToken string `json:"maingate_api_token"`
|
||||
RedisURL string `json:"tavern_redis_url"`
|
||||
Group2 map[string]configDocument `json:"tavern_group_types"`
|
||||
MaingateApiToken string `json:"maingate_api_token"`
|
||||
RedisURL string `json:"tavern_redis_url"`
|
||||
macAddr string
|
||||
}
|
||||
|
||||
@ -90,7 +84,7 @@ type subTavern struct {
|
||||
wsh *wshandler.WebsocketHandler
|
||||
region string
|
||||
groups map[string]group
|
||||
methods map[string]reflect.Method
|
||||
apiFuncs *apiFuncsContainer
|
||||
}
|
||||
|
||||
func getMacAddr() (string, error) {
|
||||
@ -147,15 +141,6 @@ func (tv *Tavern) prepare(ctx context.Context) error {
|
||||
for region, addr := range config.RegionStorage {
|
||||
var dbconn gocommon.MongoClient
|
||||
var err error
|
||||
var groupinstance group
|
||||
|
||||
var tmp *subTavern
|
||||
methods := make(map[string]reflect.Method)
|
||||
tp := reflect.TypeOf(tmp)
|
||||
for i := 0; i < tp.NumMethod(); i++ {
|
||||
method := tp.Method(i)
|
||||
methods[method.Name] = method
|
||||
}
|
||||
|
||||
redisClient, err := gocommon.NewRedisClient(addr.Redis["tavern"])
|
||||
if err != nil {
|
||||
@ -167,30 +152,32 @@ func (tv *Tavern) prepare(ctx context.Context) error {
|
||||
mongoClient: dbconn,
|
||||
redisClient: redisClient,
|
||||
region: region,
|
||||
methods: methods,
|
||||
apiFuncs: &apiFuncsContainer{
|
||||
normfuncs: make(map[string]apiFuncType),
|
||||
funcs: make(map[string][]apiFuncType),
|
||||
},
|
||||
}
|
||||
|
||||
groups := make(map[string]group)
|
||||
for typename, cfg := range config.GroupTypes {
|
||||
cfg.Name = typename
|
||||
if cfg.Transient {
|
||||
groupinstance, err = cfg.prepareInMemory(ctx, typename, sub)
|
||||
//} else {
|
||||
// TODO : db
|
||||
// if !dbconn.Connected() {
|
||||
// dbconn, err = gocommon.NewMongoClient(ctx, url.Mongo, region)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// }
|
||||
// groupinstance, err = cfg.preparePersistent(ctx, region, dbconn, tv.wsh)
|
||||
for typename, cfg := range config.Group2 {
|
||||
gtype, ok := groupTypeContainer()[typename]
|
||||
if !ok {
|
||||
return fmt.Errorf("%s group type is not valid", typename)
|
||||
}
|
||||
if err != nil {
|
||||
|
||||
if !gtype.Implements(reflect.TypeOf((*group)(nil)).Elem()) {
|
||||
return fmt.Errorf("%s is not implement proper interface", typename)
|
||||
}
|
||||
ptrvalue := reflect.New(gtype.Elem())
|
||||
instance := ptrvalue.Interface().(group)
|
||||
if err := instance.Initialize(sub, cfg); err != nil {
|
||||
return err
|
||||
}
|
||||
groups[typename] = groupinstance
|
||||
groups[typename] = instance
|
||||
}
|
||||
|
||||
sub.groups = groups
|
||||
sub.apiFuncs.normalize()
|
||||
|
||||
tv.subTaverns = append(tv.subTaverns, sub)
|
||||
}
|
||||
@ -216,44 +203,37 @@ func (tv *Tavern) RegisterHandlers(ctx context.Context, serveMux *http.ServeMux,
|
||||
func (sub *subTavern) OnClientMessageReceived(sender *wshandler.Sender, messageType wshandler.WebSocketMessageType, body io.Reader) {
|
||||
if messageType == wshandler.Connected {
|
||||
logger.Println("OnClientMessageReceived : connected ", sender.Accid.Hex())
|
||||
sub.redisClient.HSet(sub.redisClient.Context(), sender.Accid.Hex(), "_ts", time.Now().UTC().Unix()).Result()
|
||||
|
||||
for _, gt := range sub.groups {
|
||||
gt.ClientMessageReceved(sender, messageType, nil)
|
||||
}
|
||||
} else if messageType == wshandler.Disconnected {
|
||||
var rooms []string
|
||||
dec := json.NewDecoder(body)
|
||||
if err := dec.Decode(&rooms); err == nil {
|
||||
for _, roomname := range rooms {
|
||||
for _, gt := range sub.groups {
|
||||
gt.MemberDisconnected(roomname, sender.Accid)
|
||||
}
|
||||
for _, gt := range sub.groups {
|
||||
gt.ClientMessageReceved(sender, messageType, rooms)
|
||||
}
|
||||
}
|
||||
sub.redisClient.Del(sub.redisClient.Context(), sender.Accid.Hex()).Result()
|
||||
logger.Println("OnClientMessageReceived : disconnected ", sender.Accid.Hex())
|
||||
} else if messageType == wshandler.BinaryMessage {
|
||||
var msg map[string][]any
|
||||
var commandline []any
|
||||
dec := json.NewDecoder(body)
|
||||
if err := dec.Decode(&msg); err == nil {
|
||||
for cmd, args := range msg {
|
||||
switch cmd {
|
||||
case "EnterChannel":
|
||||
sub.wsh.EnterRoom(sub.region, args[0].(string), sender.Accid)
|
||||
if err := dec.Decode(&commandline); err == nil {
|
||||
cmd := commandline[0].(string)
|
||||
args := commandline[1:]
|
||||
switch cmd {
|
||||
case "EnterChannel":
|
||||
sub.wsh.EnterRoom(sub.region, args[0].(string), sender.Accid)
|
||||
|
||||
case "LeaveChannel":
|
||||
sub.wsh.LeaveRoom(sub.region, args[0].(string), sender.Accid)
|
||||
case "LeaveChannel":
|
||||
sub.wsh.LeaveRoom(sub.region, args[0].(string), sender.Accid)
|
||||
|
||||
case "UpdateGroupMemberDocument":
|
||||
typename := args[0].(string)
|
||||
gidobj, _ := primitive.ObjectIDFromHex(args[1].(string))
|
||||
doc := args[2].(map[string]any)
|
||||
if group := sub.groups[typename]; group != nil {
|
||||
group.UpdateMemberDocument(gidobj, sender.Accid, doc)
|
||||
}
|
||||
|
||||
case "UpdateGroupDocument":
|
||||
typename := args[0].(string)
|
||||
gidobj, _ := primitive.ObjectIDFromHex(args[1].(string))
|
||||
doc := args[2].(map[string]any)
|
||||
if group := sub.groups[typename]; group != nil {
|
||||
group.UpdateGroupDocument(gidobj, doc)
|
||||
}
|
||||
default:
|
||||
for _, gt := range sub.groups {
|
||||
gt.ClientMessageReceved(sender, messageType, commandline)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -292,6 +272,9 @@ func (sub *subTavern) api(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
if r.PostForm == nil {
|
||||
r.ParseMultipartForm(defaultMaxMemory)
|
||||
}
|
||||
|
||||
operation := r.URL.Query().Get("operation")
|
||||
if len(operation) == 0 {
|
||||
@ -299,23 +282,5 @@ func (sub *subTavern) api(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
method, ok := sub.methods[operation]
|
||||
if !ok {
|
||||
// 없는 operation
|
||||
logger.Println("fail to call api. operation is not valid :", operation)
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
if r.PostForm == nil {
|
||||
r.ParseMultipartForm(defaultMaxMemory)
|
||||
}
|
||||
|
||||
args := []reflect.Value{
|
||||
reflect.ValueOf(sub),
|
||||
reflect.ValueOf(w),
|
||||
reflect.ValueOf(r),
|
||||
}
|
||||
|
||||
method.Func.Call(args)
|
||||
sub.apiFuncs.call(operation, w, r)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user