From 1922b9152b9a75dc6fb3159ce1a3dba8d169fd21 Mon Sep 17 00:00:00 2001 From: mountain Date: Thu, 15 Feb 2024 12:07:37 +0900 Subject: [PATCH] =?UTF-8?q?=EA=B7=B8=EB=A3=B9=EC=B1=97=20redis=20=ED=82=A4?= =?UTF-8?q?=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/group_chat.go | 150 +++++++++++++++++++++++++-------------------- go.mod | 2 +- go.sum | 4 +- 3 files changed, 88 insertions(+), 68 deletions(-) diff --git a/core/group_chat.go b/core/group_chat.go index 24e1724..97a53f5 100644 --- a/core/group_chat.go +++ b/core/group_chat.go @@ -106,37 +106,38 @@ func (gc *groupChat) Initialize(tv *Tavern, cfg configDocument) error { } func (gc *groupChat) ClientConnected(conn *websocket.Conn, callby *wshandler.Sender) { - gc.rh.JSONSet(callby.Accid.Hex(), "$.channel", map[string]any{}) } func (gc *groupChat) ClientDisconnected(msg string, callby *wshandler.Sender) { - docs, _ := gc.rh.JSONGetDocuments(callby.Accid.Hex(), "$.channel") - logger.Println("groupchat ClientDisconnected docs :", callby.Alias, docs) + if msg == wshandler.ForceShutdownCloseMessage { + gc.rh.Del(gc.rh.Context(), "gc-"+callby.Accid.Hex()).Result() + return + } - if len(docs) > 0 { - for k, v := range docs[0] { - typename := k - chanid := v.(string) - gc.leaveRoom(chanid, callby.Accid) - if k == "public" { - cnt, err := gc.rh.JSONDel(chanid, "$.members."+callby.Alias) - if cnt > 0 { - if cfg, ok := gc.chatConfig.Channels[chanid]; ok { - cfg.inoutChan <- "-" + callby.Alias - } - } else if err != nil { - logger.Println("groupchat ClientDisconnected JSONDel err :", err, callby.Alias) - } else { - logger.Println("groupchat ClientDisconnected JSONDel cnt 0 :", callby.Alias) + chans, _ := gc.rh.HGetAll(gc.rh.Context(), "gc-"+callby.Accid.Hex()).Result() + gc.rh.Del(gc.rh.Context(), "gc-"+callby.Accid.Hex()).Result() + + for typename, chanid := range chans { + gc.leaveRoom(chanid, callby.Accid) + if typename == "public" { + cnt, err := gc.rh.JSONDel(chanid, "$.members."+callby.Alias) + if cnt > 0 { + gc.rh.JSONNumIncrBy(chanid, "$.size", -1) + if cfg, ok := gc.chatConfig.Channels[chanid]; ok { + cfg.inoutChan <- "-" + callby.Alias } + } else if err != nil { + logger.Println("groupchat ClientDisconnected JSONDel err :", err, callby.Alias) } else { - logger.Println("groupchat ClientDisconnected leave private channel :", chanid, callby.Alias) - gc.sendUpstreamMessage(&wshandler.UpstreamMessage{ - Target: "#" + chanid, - Body: map[string]any{"sender": callby.Alias}, - Tag: []string{typename + ".LeavePrivateChannel"}, - }) + logger.Println("groupchat ClientDisconnected JSONDel cnt 0 :", callby.Alias) } + } else { + logger.Println("groupchat ClientDisconnected leave private channel :", chanid, callby.Alias) + gc.sendUpstreamMessage(&wshandler.UpstreamMessage{ + Target: "#" + chanid, + Body: map[string]any{"sender": callby.Alias}, + Tag: []string{typename + ".LeavePrivateChannel"}, + }) } } } @@ -145,52 +146,71 @@ func (gc *groupChat) EnterPublicChannel(ctx wshandler.ApiCallContext) { gc.LeavePublicChannel(ctx) chanid := ctx.Arguments[0].(string) - if cfg, ok := gc.chatConfig.Channels[chanid]; ok { - size, err := gc.rh.JSONObjLen(chanid, "$.members") - if err != nil { - logger.Println("JSONGetInt64 failed :", chanid, err) - } else if len(size) == 0 || size[0] < cfg.Capacity { - // 입장 - _, err := gc.rh.JSONSet(chanid, "$.members."+ctx.CallBy.Alias, 1) - if err == nil { - logger.Println("groupchat EnterPublicChannel JSONSet :", chanid, ctx.CallBy.Alias) - gc.enterRoom(chanid, ctx.CallBy.Accid) - gc.rh.JSONSet(ctx.CallBy.Accid.Hex(), "$.channel.public", chanid) - cfg.inoutChan <- "+" + ctx.CallBy.Alias + cfg, ok := gc.chatConfig.Channels[chanid] + if !ok { + return + } - members, err := gc.rh.JSONGetDocuments(chanid, "$.members") - if err != nil { - logger.Println("JSONGetDocuments failed :", chanid, err) - } + atomicsize, _ := gc.rh.JSONNumIncrBy(chanid, "$.size", 1) + if len(atomicsize) == 0 { + return + } - toarr := make([]string, 0, len(members[0])) - for k := range members[0] { - toarr = append(toarr, k) - } + if atomicsize[0] > cfg.Capacity { + logger.Println("chatting channel is full :", chanid, atomicsize[0]-1, cfg.Capacity) + gc.rh.JSONNumIncrBy(chanid, "$.size", -1) + return + } - gc.sendUpstreamMessage(&wshandler.UpstreamMessage{ - Target: ctx.CallBy.Accid.Hex(), - Body: map[string]any{"members": toarr}, - Tag: []string{"ChattingChannelProperties"}, - }) - } else { - logger.Println("JSONSet $.members failed :", chanid, *ctx.CallBy, err) - logger.Println(gc.rh.JSONGet(chanid, "$")) - } - } else { - // 풀방 - logger.Println("chatting channel is full :", chanid, size, cfg.Capacity) + cnt, _ := gc.rh.HSet(gc.rh.Context(), "gc-"+ctx.CallBy.Accid.Hex(), "public", chanid).Result() + if cnt == 0 { + logger.Println("HSet cnt 0 :", chanid, ctx.CallBy.Alias) + return + } + + ok, err := gc.rh.JSONSet(chanid, "$.members."+ctx.CallBy.Alias, 1) + if err != nil { + gc.rh.HDel(gc.rh.Context(), "gc-"+ctx.CallBy.Accid.Hex(), "public").Result() + logger.Println("JSONSet $.members failed :", err, chanid, ctx.CallBy.Alias) + return + } + + if !ok { + gc.rh.HDel(gc.rh.Context(), "gc-"+ctx.CallBy.Accid.Hex(), "public").Result() + logger.Println("JSONSet $.members not ok :", chanid, ctx.CallBy.Alias) + return + } + + logger.Println("groupchat EnterPublicChannel JSONSet :", chanid, ctx.CallBy.Alias) + gc.enterRoom(chanid, ctx.CallBy.Accid) + cfg.inoutChan <- "+" + ctx.CallBy.Alias + + members, _ := gc.rh.JSONGetDocuments(chanid, "$.members") + var toarr []string + if len(members) > 0 { + toarr = make([]string, 0, len(members[0])) + for k := range members[0] { + toarr = append(toarr, k) } } else { - logger.Println("chatting channel not valid :", chanid) + toarr = []string{} } + + gc.sendUpstreamMessage(&wshandler.UpstreamMessage{ + Target: ctx.CallBy.Accid.Hex(), + Body: map[string]any{"members": toarr}, + Tag: []string{"ChattingChannelProperties"}, + }) } func (gc *groupChat) LeavePublicChannel(ctx wshandler.ApiCallContext) { - oldchans, _ := gc.rh.JSONGetString(ctx.CallBy.Accid.Hex(), "$.channel.public") - for _, oldchan := range oldchans { + oldchan, _ := gc.rh.HGet(gc.rh.Context(), "gc-"+ctx.CallBy.Accid.Hex(), "public").Result() + if len(oldchan) > 0 { + gc.rh.HDel(gc.rh.Context(), "gc-"+ctx.CallBy.Accid.Hex(), "public") + cnt, err := gc.rh.JSONDel(oldchan, "$.members."+ctx.CallBy.Alias) if cnt > 0 { + gc.rh.JSONNumIncrBy(oldchan, "$.size", -1) logger.Println("groupchat LeavePublicChannel JSONDel :", oldchan, ctx.CallBy.Alias) gc.leaveRoom(oldchan, ctx.CallBy.Accid) if cfg, ok := gc.chatConfig.Channels[oldchan]; ok { @@ -202,7 +222,6 @@ func (gc *groupChat) LeavePublicChannel(ctx wshandler.ApiCallContext) { logger.Println("groupchat LeavePublicChannel JSONDel cnt 0 :", oldchan, ctx.CallBy.Alias) } } - gc.rh.JSONDel(ctx.CallBy.Accid.Hex(), "$.channel.public") } func (gc *groupChat) TextMessage(ctx wshandler.ApiCallContext) { @@ -225,7 +244,7 @@ func (gc *groupChat) EnterPrivateChannel(ctx wshandler.ApiCallContext) { if len(reason) > 0 { // 수락 - ok, err := gc.rh.JSONSet(ctx.CallBy.Accid.Hex(), "$.channel."+typename, channel, gocommon.RedisonSetOptionNX) + ok, err := gc.rh.HSetNX(gc.rh.Context(), "gc-"+ctx.CallBy.Accid.Hex(), typename, channel).Result() if err != nil || !ok { // 이미 다른 private channel 참여 중 logger.Println("EnterPrivateChannel failed. HSetNX return err :", err, ctx.CallBy.Accid.Hex(), typename, channel) @@ -247,7 +266,7 @@ func (gc *groupChat) EnterPrivateChannel(ctx wshandler.ApiCallContext) { func (gc *groupChat) LeavePrivateChannel(ctx wshandler.ApiCallContext) { typename := ctx.Arguments[0].(string) chanid := ctx.Arguments[1].(string) - cnt, _ := gc.rh.JSONDel(ctx.CallBy.Accid.Hex(), "$.channel."+typename) + cnt, _ := gc.rh.HDel(gc.rh.Context(), "gc-"+ctx.CallBy.Accid.Hex(), typename).Result() if cnt > 0 { gc.leaveRoom(chanid, ctx.CallBy.Accid) gc.sendUpstreamMessage(&wshandler.UpstreamMessage{ @@ -306,14 +325,15 @@ func (gc *groupChat) QueryPlayerChattingChannel(w http.ResponseWriter, r *http.R return } - sub, err := gc.rh.JSONGetDocuments(accid.Hex(), "$.channel") + sub, err := gc.rh.HGetAll(gc.rh.Context(), "gc-"+accid.Hex()).Result() if err != nil { w.WriteHeader(http.StatusInternalServerError) return } - if len(sub) > 0 { - gocommon.MakeEncoder(w, r).Encode(sub[0]) + if sub == nil { + sub = make(map[string]string) } + gocommon.MakeEncoder(w, r).Encode(sub) } func (gc *groupChat) SendMessageOnChannel(w http.ResponseWriter, r *http.Request) { diff --git a/go.mod b/go.mod index 3d8444a..b31a181 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/go-redis/redis/v8 v8.11.5 github.com/gorilla/websocket v1.5.0 go.mongodb.org/mongo-driver v1.11.7 - repositories.action2quare.com/ayo/gocommon v0.0.0-20240201092859-c71a74762de7 + repositories.action2quare.com/ayo/gocommon v0.0.0-20240215030631-0c5ddac9f55f ) require ( diff --git a/go.sum b/go.sum index b3eab92..2459142 100644 --- a/go.sum +++ b/go.sum @@ -125,5 +125,5 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -repositories.action2quare.com/ayo/gocommon v0.0.0-20240201092859-c71a74762de7 h1:ikDwKNiRXJlIBueAVmp9p2To+lRN9zTzGSvVHCXgFnI= -repositories.action2quare.com/ayo/gocommon v0.0.0-20240201092859-c71a74762de7/go.mod h1:Gb418rT96M3K7L/XMPzp8IJj4UXVunq7dZzrxsMBz/8= +repositories.action2quare.com/ayo/gocommon v0.0.0-20240215030631-0c5ddac9f55f h1:ZIDd5JCXlPCVj2656Bqm/yiI0cZzgIa51IOs5AljEAA= +repositories.action2quare.com/ayo/gocommon v0.0.0-20240215030631-0c5ddac9f55f/go.mod h1:Gb418rT96M3K7L/XMPzp8IJj4UXVunq7dZzrxsMBz/8=