채팅 멤버 목록 전파

This commit is contained in:
2023-10-12 14:46:54 +09:00
parent bdcb86c1c7
commit dd37659089

View File

@ -5,10 +5,11 @@ import (
"fmt" "fmt"
"net/http" "net/http"
"strings" "strings"
"time"
"github.com/go-redis/redis/v8" "github.com/go-redis/redis/v8"
"go.mongodb.org/mongo-driver/bson/primitive"
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
"go.mongodb.org/mongo-driver/bson/primitive"
"repositories.action2quare.com/ayo/gocommon" "repositories.action2quare.com/ayo/gocommon"
"repositories.action2quare.com/ayo/gocommon/logger" "repositories.action2quare.com/ayo/gocommon/logger"
"repositories.action2quare.com/ayo/gocommon/wshandler" "repositories.action2quare.com/ayo/gocommon/wshandler"
@ -16,10 +17,12 @@ import (
type channelID = string type channelID = string
type channelConfig struct { type channelConfig struct {
Capacity int64 `json:"capacity"` Capacity int64 `json:"capacity"`
Size int64 `json:"size"` Size int64 `json:"size"`
Key string `json:"key"` Key string `json:"key"`
Members map[string]int32 `json:"members"`
emptyJson string emptyJson string
inoutChan chan string
} }
type chatConfig struct { type chatConfig struct {
@ -62,7 +65,7 @@ func (gc *groupChat) Initialize(tv *Tavern, cfg configDocument) error {
jm, _ := json.Marshal(cfg) jm, _ := json.Marshal(cfg)
cfg.emptyJson = fmt.Sprintf("[%s]", string(jm)) cfg.emptyJson = fmt.Sprintf("[%s]", string(jm))
cfg.Members = make(map[string]int32)
_, err := gc.rh.JSONSet(name, "$", cfg) _, err := gc.rh.JSONSet(name, "$", cfg)
if *devflag && err != nil { if *devflag && err != nil {
gc.rh.JSONDel(name, "$") gc.rh.JSONDel(name, "$")
@ -72,6 +75,31 @@ func (gc *groupChat) Initialize(tv *Tavern, cfg configDocument) error {
if err != nil { if err != nil {
return err 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 return nil
@ -91,6 +119,9 @@ func (gc *groupChat) ClientDisconnected(conn *websocket.Conn, callby *wshandler.
gc.leaveRoom(chanid, callby.Accid) gc.leaveRoom(chanid, callby.Accid)
if k == "public" { if k == "public" {
gc.rh.JSONNumIncrBy(chanid, "$.size", -1) gc.rh.JSONNumIncrBy(chanid, "$.size", -1)
if cfg, ok := gc.chatConfig.Channels[chanid]; ok {
cfg.inoutChan <- "-" + callby.Alias
}
} else { } else {
gc.sendUpstreamMessage(&wshandler.UpstreamMessage{ gc.sendUpstreamMessage(&wshandler.UpstreamMessage{
Target: "#" + chanid, Target: "#" + chanid,
@ -105,20 +136,34 @@ func (gc *groupChat) ClientDisconnected(conn *websocket.Conn, callby *wshandler.
func (gc *groupChat) EnterPublicChannel(ctx wshandler.ApiCallContext) { func (gc *groupChat) EnterPublicChannel(ctx wshandler.ApiCallContext) {
chanid := ctx.Arguments[0].(string) chanid := ctx.Arguments[0].(string)
if cfg, ok := gc.chatConfig.Channels[chanid]; ok { if cfg, ok := gc.chatConfig.Channels[chanid]; ok {
size, err := gc.rh.JSONGetInt64(chanid, "$.size") size, err := gc.rh.JSONObjLen(chanid, "$.members")
if err != nil || len(size) == 0 { if err != nil {
logger.Println("JSONGetInt64 failed :", chanid, err) 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 { if err == nil {
gc.enterRoom(chanid, ctx.CallBy.Accid) gc.enterRoom(chanid, ctx.CallBy.Accid)
gc.rh.JSONSet(ctx.CallBy.Accid.Hex(), "$.channel.public", chanid) 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{ gc.sendUpstreamMessage(&wshandler.UpstreamMessage{
Target: "#" + chanid, Target: ctx.CallBy.Accid.Hex(),
Body: map[string]any{"size": newsize[0]}, Body: map[string]any{"members": toarr},
Tag: []string{"ChattingChannelProperties"}, Tag: []string{"ChattingChannelProperties"},
}) })
} else {
logger.Println("JSONArrAppend failed :", chanid, err)
} }
} else { } else {
// 풀방 // 풀방
@ -135,6 +180,9 @@ func (gc *groupChat) LeavePublicChannel(ctx wshandler.ApiCallContext) {
if cnt > 0 { if cnt > 0 {
gc.leaveRoom(chanid, ctx.CallBy.Accid) gc.leaveRoom(chanid, ctx.CallBy.Accid)
gc.rh.JSONNumIncrBy(chanid, "$.size", -1) gc.rh.JSONNumIncrBy(chanid, "$.size", -1)
if cfg, ok := gc.chatConfig.Channels[chanid]; ok {
cfg.inoutChan <- "-" + ctx.CallBy.Alias
}
} }
} }