diff --git a/domain/model/group_m/mic.go b/domain/model/group_m/mic.go index cb0e44885010e865b195a50e4bee029a36e57ac7..e4fecae405bad65ff1f2d6bc4839ade91c979aee 100644 --- a/domain/model/group_m/mic.go +++ b/domain/model/group_m/mic.go @@ -186,6 +186,7 @@ func UpdateMicExpire(model *domain.Model, groupUuid string, externalId string) e //2022-07-20 升级,判断是自己是否已经在别的麦上了 //const micInScript = "local flag = redis.call('SET', '{prefixGroupMicUser}', '{micUserStr}', 'ex', '{micExpire}', 'nx') if flag ~= false then redis.call('SETEX', '{prefixGroupUserMic}', '{micExpire}', '{groupUserStr}') return 1 end return 2 " const micInScript = "local flag = redis.call('EXISTS', '{prefixGroupUserMic}') if flag == 0 then local flag1 = redis.call('SET', '{prefixGroupMicUser}', '{micUserStr}', 'ex', '{micExpire}', 'nx') if flag1 ~= false then redis.call('SETEX', '{prefixGroupUserMic}', '{micExpire}', '{groupUserStr}') return 1 end return 2 end return 3" +const micUpdateScript = "local flag = redis.call('EXISTS', '{prefixGroupUserMic}') if flag == 1 then local flag1 = redis.call('SET', '{prefixGroupMicUser}', '{micUserStr}', 'ex', '{micExpire}', 'nx') if flag1 ~= false then redis.call('SETEX', '{prefixGroupUserMic}', '{micExpire}', '{groupUserStr}') return 1 end return 2 end return 3" // @@ -266,6 +267,83 @@ func (mic *Mic) In(userId uint64, externalId string, cpUserId uint64) error { return nil } +//上麦(自己), +//规则:1:加锁了不能上麦 2:麦上有人,不能上麦 +//cpUserId如果有 +func (mic *Mic) Update(userId uint64, externalId string, cpUserId uint64) error { + // 群是否被封禁, 呃,,,呃,,,呃,,, + banned := GroupBanned{ImGroupId: mic.GroupUuid} + if err := banned.Get(mic.model); err != gorm.ErrRecordNotFound { + return bizerr.GroupIsBanned + } + //判断群组设置上的麦 是否被关闭 + groupInfo, err := GetGroupInfo(mic.model, mic.GroupUuid) + if err != nil { + return err + } + if groupInfo.MicOn == false { + return bizerr.GroupInfoMicClosed + } + + //麦被加锁了 + if mic.Lock { + return bizerr.GroupMicLock + } + //设置值到redis + micUserStr, err := micUserToStr(MicUser{ + GroupUuid: mic.GroupUuid, + I: mic.I, + ExternalId: externalId, + UserId: userId, + CpUserId: cpUserId, + Forbid: false, + Timestamp: time.Now().Unix(), + }) + if err != nil { + return err + } + //加入到麦上可能有人的集合中。 + groupMicHasIn(mic.model, mic.GroupUuid, userId) + + //lua上麦,让麦上的人同人在麦上,保持原子性操作 + //清理脚本,不然redis占用内存越来越高,并且不会释放 + groupUserStr, err := userInMicToStr(mic.GroupUuid, mic.I, userId) + if err != nil { + return err + } + script := strings.Replace(strings.Replace( + strings.Replace( + strings.Replace( + strings.Replace(micUpdateScript, + "{micExpire}", strconv.Itoa(expireMinute), -1), + "{prefixGroupMicUser}", redis_key.GetPrefixGroupMicUser(mic.GroupUuid, mic.I), -1), + "{micUserStr}", micUserStr, -1), + "{prefixGroupUserMic}", redis_key.GetPrefixGroupUserInMic(externalId), -1), + "{groupUserStr}", groupUserStr, -1) + r, err := redis2.NewScript(script).Run(context.Background(), redisCli.GetRedis(), []string{}).Result() + mic.model.Log.Infof("micUser In micInScript:%v, result:%v", script, r) + d := r.(int64) + if err != nil { + return myerr.WrapErr(err) + } + if d == int64(2) { + return bizerr.GroupMicHasUser + } + if d == int64(3) { + return bizerr.GroupMicUserHasIn + } + + //离开动作已结束,增加到队列中 + MicChangeRPush(mic.model, mic.GroupUuid, mic.I) + + // 发信令,让前端重新拉取,接受容错, + sendSignalMsg(mic.model, mic.GroupUuid, GroupSystemMsg{ + MsgId: group_e.GroupMicInSignal, + Source: externalId, + }, false) + return nil +} + const micLeaveScript = "local flag = redis.call('DEL', '{prefixGroupMicUser}') if flag == 1 then return redis.call('Del', '{prefixGroupUserMic}') end return 2 " //离开麦(自己) diff --git a/domain/service/group_mic_s/group_mic.go b/domain/service/group_mic_s/group_mic.go index df6c52e601227cefa086fca8f9a48a2b93bb8217..546d608bf8e98e3c35c7bc89c6d0457e0fa49cf1 100644 --- a/domain/service/group_mic_s/group_mic.go +++ b/domain/service/group_mic_s/group_mic.go @@ -167,7 +167,7 @@ func (s *GroupMicService) GroupMicIn(groupUuid string, i int, userId uint64, ext if err != nil { return err } - return mic.In(cpUserId, user.ExternalId, userId) + return mic.Update(cpUserId, user.ExternalId, userId) }) } return nil