package core import ( "context" "io" "net/http" "github.com/go-redis/redis/v8" "repositories.action2quare.com/ayo/gocommon" "repositories.action2quare.com/ayo/gocommon/flagx" "repositories.action2quare.com/ayo/gocommon/logger" "repositories.action2quare.com/ayo/gocommon/session" "repositories.action2quare.com/ayo/gocommon/wshandler" ) var devflag = flagx.Bool("dev", false, "") type SocialConfig struct { session.SessionConfig `json:",inline"` MaingateApiToken string `json:"maingate_api_token"` RedisURL string `json:"social_redis_url"` MongoURL string `json:"social_storage_url"` FriendsMax int `json:"social_friends_max"` } var config SocialConfig type Social struct { wsh *wshandler.WebsocketHandler mongoClient gocommon.MongoClient redison *gocommon.RedisonHandler httpApiBorker gocommon.HttpApiBroker } // New : func New(ctx context.Context, wsh *wshandler.WebsocketHandler, inconfig *SocialConfig) (*Social, error) { if inconfig == nil { var loaded SocialConfig if err := gocommon.LoadConfig(&loaded); err != nil { return nil, err } inconfig = &loaded } config = *inconfig opt, err := redis.ParseURL(config.RedisURL) if err != nil { return nil, logger.ErrorWithCallStack(err) } mc, err := gocommon.NewMongoClient(ctx, config.MongoURL) if err != nil { return nil, logger.ErrorWithCallStack(err) } so := &Social{ wsh: wsh, redison: gocommon.NewRedisonHandler(ctx, redis.NewClient(opt)), mongoClient: mc, } if err := so.prepare(ctx); err != nil { logger.Println("social prepare() failed :", err) return nil, logger.ErrorWithCallStack(err) } return so, nil } func (so *Social) Cleanup() { so.mongoClient.Close() } func (so *Social) prepare(ctx context.Context) error { redisClient, err := gocommon.NewRedisClient(config.RedisURL) if err != nil { return logger.ErrorWithCallStack(err) } so.redison = gocommon.NewRedisonHandler(redisClient.Context(), redisClient) connections := makeConnections(so.redison, so.wsh) so.wsh.AddHandler(wshandler.MakeWebsocketApiHandler(connections, "social")) so.httpApiBorker.AddHandler(gocommon.MakeHttpApiHandler(connections, "social")) blocks, err := makeBlocklist(ctx, so, connections) if err != nil { return logger.ErrorWithCallStack(err) } so.wsh.AddHandler(wshandler.MakeWebsocketApiHandler(blocks, "social")) so.httpApiBorker.AddHandler(gocommon.MakeHttpApiHandler(blocks, "social")) friends, err := makeFriends(ctx, so, connections) if err != nil { return logger.ErrorWithCallStack(err) } so.wsh.AddHandler(wshandler.MakeWebsocketApiHandler(friends, "social")) so.httpApiBorker.AddHandler(gocommon.MakeHttpApiHandler(friends, "social")) invitation, err := makeInvitation(ctx, so, friends) if err != nil { return logger.ErrorWithCallStack(err) } so.wsh.AddHandler(wshandler.MakeWebsocketApiHandler(invitation, "social")) so.httpApiBorker.AddHandler(gocommon.MakeHttpApiHandler(invitation, "social")) return nil } func (so *Social) RegisterHandlers(ctx context.Context, serveMux *http.ServeMux, prefix string) error { so.wsh.AddHandler(wshandler.MakeWebsocketApiHandler(so, "social")) pattern := gocommon.MakeHttpHandlerPattern(prefix, "api") serveMux.HandleFunc(pattern, so.api) return nil } func (so *Social) api(w http.ResponseWriter, r *http.Request) { defer func() { s := recover() if s != nil { logger.Error(s) } io.Copy(io.Discard, r.Body) r.Body.Close() }() // 서버에서 오는 요청만 처리 apitoken := r.Header.Get("MG-X-API-TOKEN") if apitoken != config.MaingateApiToken { // 서버가 보내는 쿼리만 허용 logger.Println("MG-X-API-TOKEN is missing") w.WriteHeader(http.StatusBadRequest) return } so.httpApiBorker.Call(w, r) }