From dd3765908997d636bd1952ee00e8b886cb3cfe61 Mon Sep 17 00:00:00 2001 From: mountain Date: Thu, 12 Oct 2023 14:46:54 +0900 Subject: [PATCH] =?UTF-8?q?=EC=B1=84=ED=8C=85=20=EB=A9=A4=EB=B2=84=20?= =?UTF-8?q?=EB=AA=A9=EB=A1=9D=20=EC=A0=84=ED=8C=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/group_chat.go | 70 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 59 insertions(+), 11 deletions(-) diff --git a/core/group_chat.go b/core/group_chat.go index 8cbc71f..5bba109 100644 --- a/core/group_chat.go +++ b/core/group_chat.go @@ -5,10 +5,11 @@ import ( "fmt" "net/http" "strings" + "time" "github.com/go-redis/redis/v8" - "go.mongodb.org/mongo-driver/bson/primitive" "github.com/gorilla/websocket" + "go.mongodb.org/mongo-driver/bson/primitive" "repositories.action2quare.com/ayo/gocommon" "repositories.action2quare.com/ayo/gocommon/logger" "repositories.action2quare.com/ayo/gocommon/wshandler" @@ -16,10 +17,12 @@ import ( type channelID = string type channelConfig struct { - Capacity int64 `json:"capacity"` - Size int64 `json:"size"` - Key string `json:"key"` + Capacity int64 `json:"capacity"` + Size int64 `json:"size"` + Key string `json:"key"` + Members map[string]int32 `json:"members"` emptyJson string + inoutChan chan string } type chatConfig struct { @@ -62,7 +65,7 @@ func (gc *groupChat) Initialize(tv *Tavern, cfg configDocument) error { jm, _ := json.Marshal(cfg) cfg.emptyJson = fmt.Sprintf("[%s]", string(jm)) - + cfg.Members = make(map[string]int32) _, err := gc.rh.JSONSet(name, "$", cfg) if *devflag && err != nil { gc.rh.JSONDel(name, "$") @@ -72,6 +75,31 @@ func (gc *groupChat) Initialize(tv *Tavern, cfg configDocument) error { if err != nil { return err } + + inoutchan := make(chan string, 10) + cfg.inoutChan = inoutchan + + go func(chanid string) { + var cur []string + tick := time.After(3 * time.Second) + for { + select { + case <-tick: + tick = time.After(3 * time.Second) + if len(cur) > 0 { + gc.sendUpstreamMessage(&wshandler.UpstreamMessage{ + Target: "#" + chanid, + Body: map[string]any{"inout": cur}, + Tag: []string{"ChattingChannelProperties"}, + }) + cur = nil + } + + case m := <-inoutchan: + cur = append(cur, m) + } + } + }(name) } return nil @@ -91,6 +119,9 @@ func (gc *groupChat) ClientDisconnected(conn *websocket.Conn, callby *wshandler. gc.leaveRoom(chanid, callby.Accid) if k == "public" { gc.rh.JSONNumIncrBy(chanid, "$.size", -1) + if cfg, ok := gc.chatConfig.Channels[chanid]; ok { + cfg.inoutChan <- "-" + callby.Alias + } } else { gc.sendUpstreamMessage(&wshandler.UpstreamMessage{ Target: "#" + chanid, @@ -105,20 +136,34 @@ func (gc *groupChat) ClientDisconnected(conn *websocket.Conn, callby *wshandler. func (gc *groupChat) EnterPublicChannel(ctx wshandler.ApiCallContext) { chanid := ctx.Arguments[0].(string) if cfg, ok := gc.chatConfig.Channels[chanid]; ok { - size, err := gc.rh.JSONGetInt64(chanid, "$.size") - if err != nil || len(size) == 0 { + size, err := gc.rh.JSONObjLen(chanid, "$.members") + if err != nil { logger.Println("JSONGetInt64 failed :", chanid, err) - } else if size[0] < cfg.Capacity { + } else if len(size) == 0 || size[0] < cfg.Capacity { // 입장 - newsize, err := gc.rh.JSONNumIncrBy(chanid, "$.size", 1) + _, err := gc.rh.JSONSet(chanid, "$.members."+ctx.CallBy.Alias, 1) if err == nil { 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])) + for k := range members[0] { + toarr = append(toarr, k) + } + gc.sendUpstreamMessage(&wshandler.UpstreamMessage{ - Target: "#" + chanid, - Body: map[string]any{"size": newsize[0]}, + Target: ctx.CallBy.Accid.Hex(), + Body: map[string]any{"members": toarr}, Tag: []string{"ChattingChannelProperties"}, }) + } else { + logger.Println("JSONArrAppend failed :", chanid, err) } } else { // 풀방 @@ -135,6 +180,9 @@ func (gc *groupChat) LeavePublicChannel(ctx wshandler.ApiCallContext) { if cnt > 0 { gc.leaveRoom(chanid, ctx.CallBy.Accid) gc.rh.JSONNumIncrBy(chanid, "$.size", -1) + if cfg, ok := gc.chatConfig.Channels[chanid]; ok { + cfg.inoutChan <- "-" + ctx.CallBy.Alias + } } }