그룹챗 redis 키 분리

This commit is contained in:
2024-02-15 12:07:37 +09:00
parent 7b2aa046bd
commit 1922b9152b
3 changed files with 88 additions and 68 deletions

View File

@ -106,21 +106,23 @@ func (gc *groupChat) Initialize(tv *Tavern, cfg configDocument) error {
} }
func (gc *groupChat) ClientConnected(conn *websocket.Conn, callby *wshandler.Sender) { 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) { func (gc *groupChat) ClientDisconnected(msg string, callby *wshandler.Sender) {
docs, _ := gc.rh.JSONGetDocuments(callby.Accid.Hex(), "$.channel") if msg == wshandler.ForceShutdownCloseMessage {
logger.Println("groupchat ClientDisconnected docs :", callby.Alias, docs) gc.rh.Del(gc.rh.Context(), "gc-"+callby.Accid.Hex()).Result()
return
}
if len(docs) > 0 { chans, _ := gc.rh.HGetAll(gc.rh.Context(), "gc-"+callby.Accid.Hex()).Result()
for k, v := range docs[0] { gc.rh.Del(gc.rh.Context(), "gc-"+callby.Accid.Hex()).Result()
typename := k
chanid := v.(string) for typename, chanid := range chans {
gc.leaveRoom(chanid, callby.Accid) gc.leaveRoom(chanid, callby.Accid)
if k == "public" { if typename == "public" {
cnt, err := gc.rh.JSONDel(chanid, "$.members."+callby.Alias) cnt, err := gc.rh.JSONDel(chanid, "$.members."+callby.Alias)
if cnt > 0 { if cnt > 0 {
gc.rh.JSONNumIncrBy(chanid, "$.size", -1)
if cfg, ok := gc.chatConfig.Channels[chanid]; ok { if cfg, ok := gc.chatConfig.Channels[chanid]; ok {
cfg.inoutChan <- "-" + callby.Alias cfg.inoutChan <- "-" + callby.Alias
} }
@ -138,59 +140,77 @@ func (gc *groupChat) ClientDisconnected(msg string, callby *wshandler.Sender) {
}) })
} }
} }
}
} }
func (gc *groupChat) EnterPublicChannel(ctx wshandler.ApiCallContext) { func (gc *groupChat) EnterPublicChannel(ctx wshandler.ApiCallContext) {
gc.LeavePublicChannel(ctx) gc.LeavePublicChannel(ctx)
chanid := ctx.Arguments[0].(string) chanid := ctx.Arguments[0].(string)
if cfg, ok := gc.chatConfig.Channels[chanid]; ok { cfg, ok := gc.chatConfig.Channels[chanid]
size, err := gc.rh.JSONObjLen(chanid, "$.members") if !ok {
if err != nil { return
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
members, err := gc.rh.JSONGetDocuments(chanid, "$.members")
if err != nil {
logger.Println("JSONGetDocuments failed :", chanid, err)
} }
toarr := make([]string, 0, len(members[0])) atomicsize, _ := gc.rh.JSONNumIncrBy(chanid, "$.size", 1)
if len(atomicsize) == 0 {
return
}
if atomicsize[0] > cfg.Capacity {
logger.Println("chatting channel is full :", chanid, atomicsize[0]-1, cfg.Capacity)
gc.rh.JSONNumIncrBy(chanid, "$.size", -1)
return
}
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] { for k := range members[0] {
toarr = append(toarr, k) toarr = append(toarr, k)
} }
} else {
toarr = []string{}
}
gc.sendUpstreamMessage(&wshandler.UpstreamMessage{ gc.sendUpstreamMessage(&wshandler.UpstreamMessage{
Target: ctx.CallBy.Accid.Hex(), Target: ctx.CallBy.Accid.Hex(),
Body: map[string]any{"members": toarr}, Body: map[string]any{"members": toarr},
Tag: []string{"ChattingChannelProperties"}, 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)
}
} else {
logger.Println("chatting channel not valid :", chanid)
}
} }
func (gc *groupChat) LeavePublicChannel(ctx wshandler.ApiCallContext) { func (gc *groupChat) LeavePublicChannel(ctx wshandler.ApiCallContext) {
oldchans, _ := gc.rh.JSONGetString(ctx.CallBy.Accid.Hex(), "$.channel.public") oldchan, _ := gc.rh.HGet(gc.rh.Context(), "gc-"+ctx.CallBy.Accid.Hex(), "public").Result()
for _, oldchan := range oldchans { 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) cnt, err := gc.rh.JSONDel(oldchan, "$.members."+ctx.CallBy.Alias)
if cnt > 0 { if cnt > 0 {
gc.rh.JSONNumIncrBy(oldchan, "$.size", -1)
logger.Println("groupchat LeavePublicChannel JSONDel :", oldchan, ctx.CallBy.Alias) logger.Println("groupchat LeavePublicChannel JSONDel :", oldchan, ctx.CallBy.Alias)
gc.leaveRoom(oldchan, ctx.CallBy.Accid) gc.leaveRoom(oldchan, ctx.CallBy.Accid)
if cfg, ok := gc.chatConfig.Channels[oldchan]; ok { 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) 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) { func (gc *groupChat) TextMessage(ctx wshandler.ApiCallContext) {
@ -225,7 +244,7 @@ func (gc *groupChat) EnterPrivateChannel(ctx wshandler.ApiCallContext) {
if len(reason) > 0 { 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 { if err != nil || !ok {
// 이미 다른 private channel 참여 중 // 이미 다른 private channel 참여 중
logger.Println("EnterPrivateChannel failed. HSetNX return err :", err, ctx.CallBy.Accid.Hex(), typename, 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) { func (gc *groupChat) LeavePrivateChannel(ctx wshandler.ApiCallContext) {
typename := ctx.Arguments[0].(string) typename := ctx.Arguments[0].(string)
chanid := ctx.Arguments[1].(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 { if cnt > 0 {
gc.leaveRoom(chanid, ctx.CallBy.Accid) gc.leaveRoom(chanid, ctx.CallBy.Accid)
gc.sendUpstreamMessage(&wshandler.UpstreamMessage{ gc.sendUpstreamMessage(&wshandler.UpstreamMessage{
@ -306,14 +325,15 @@ func (gc *groupChat) QueryPlayerChattingChannel(w http.ResponseWriter, r *http.R
return return
} }
sub, err := gc.rh.JSONGetDocuments(accid.Hex(), "$.channel") sub, err := gc.rh.HGetAll(gc.rh.Context(), "gc-"+accid.Hex()).Result()
if err != nil { if err != nil {
w.WriteHeader(http.StatusInternalServerError) w.WriteHeader(http.StatusInternalServerError)
return return
} }
if len(sub) > 0 { if sub == nil {
gocommon.MakeEncoder(w, r).Encode(sub[0]) sub = make(map[string]string)
} }
gocommon.MakeEncoder(w, r).Encode(sub)
} }
func (gc *groupChat) SendMessageOnChannel(w http.ResponseWriter, r *http.Request) { func (gc *groupChat) SendMessageOnChannel(w http.ResponseWriter, r *http.Request) {

2
go.mod
View File

@ -6,7 +6,7 @@ require (
github.com/go-redis/redis/v8 v8.11.5 github.com/go-redis/redis/v8 v8.11.5
github.com/gorilla/websocket v1.5.0 github.com/gorilla/websocket v1.5.0
go.mongodb.org/mongo-driver v1.11.7 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 ( require (

4
go.sum
View File

@ -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.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 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 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-20240215030631-0c5ddac9f55f h1:ZIDd5JCXlPCVj2656Bqm/yiI0cZzgIa51IOs5AljEAA=
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/go.mod h1:Gb418rT96M3K7L/XMPzp8IJj4UXVunq7dZzrxsMBz/8=