发布线上

This commit is contained in:
youngq 2024-09-02 10:13:37 +08:00
parent b6aab652a8
commit 22a15fa743
3 changed files with 105 additions and 53 deletions

View File

@ -62,29 +62,22 @@ namespace WGShare.API.Controllers.Frontend
[HttpPost("manager")] [HttpPost("manager")]
public async Task SetRoomManager([FromBody] RoomManagerInputDTO inputDTO) public async Task SetRoomManager([FromBody] RoomManagerInputDTO inputDTO)
{ {
var user = RedisHelper.Instance.HGet<ChannelUserInfo>(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, inputDTO.RoomNum), inputDTO.UserId); var users = RedisHelper.Instance.HVals<ChannelUserInfo>(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, inputDTO.RoomNum));
if (users.Count(x => x.IsRoomManager || x.RoleId == ((int)RoleEnums.Admin).ToString()) >= 32)
{
throw Oops.Oh("房间已达到20个发言人限制。请移除一位或联系管理员。");
}
var user = users.FirstOrDefault(x => x.UID == inputDTO.UserId);
if (user == null) if (user == null)
{ {
throw Oops.Oh("用户已不在房间内!"); throw Oops.Oh("用户已不在房间内!");
} }
//var entities = new RoomManager
//{
// RoomId = inputDTO.RoomId,
// UserId = inputDTO.UserId
//};
user.IsRoomManager = true; user.IsRoomManager = true;
//await _sqlSugar.Storageable(entities)
// .SplitInsert(x => !x.Any())
// .ToStorage().AsInsertable.ExecuteCommandAsync();
RedisHelper.Instance.HSet(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, inputDTO.RoomNum), inputDTO.UserId, user); RedisHelper.Instance.HSet(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, inputDTO.RoomNum), inputDTO.UserId, user);
await _hubContext.Clients.Group(inputDTO.RoomNum).ManagerRefresh(user); await _hubContext.Clients.Group(inputDTO.RoomNum).ManagerRefresh(user, UId);
} }
/// <summary> /// <summary>
@ -101,14 +94,25 @@ namespace WGShare.API.Controllers.Frontend
throw Oops.Oh("用户已不在房间内!"); throw Oops.Oh("用户已不在房间内!");
} }
//await _sqlSugar.Deleteable<RoomManager>()
// .Where(x => x.RoomId == inputDTO.RoomId && x.UserId == inputDTO.UserId)
// .ExecuteCommandAsync();
user.IsRoomManager = false; user.IsRoomManager = false;
RedisHelper.Instance.HSet(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, inputDTO.RoomNum), inputDTO.UserId, user); RedisHelper.Instance.HSet(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, inputDTO.RoomNum), inputDTO.UserId, user);
await _hubContext.Clients.Group(inputDTO.RoomNum).ManagerRefresh(user); // 判断是否显示用户
var showUserId = RedisHelper.Instance.HGet(RedisKeyConstant.SessionManage.GetChannelShowUserKey(TenantId), inputDTO.RoomNum);
if (showUserId == inputDTO.UserId)
{
// 取消显示用户,设置显示管理员
var users = RedisHelper.Instance.HVals<ChannelUserInfo>(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, inputDTO.RoomNum));
var showUser = users.FirstOrDefault(x => x.RoleId == ((int)RoleEnums.Admin).ToString() || x.IsRoomManager);
if (showUser != null)
{
RedisHelper.Instance.HSet(RedisKeyConstant.SessionManage.GetChannelShowUserKey(TenantId), inputDTO.RoomNum, showUser.UID);
await _hubContext.Clients.Group(inputDTO.RoomNum).ShowUser(showUser.UID, showUser.UserName, string.Empty, string.Empty);
}
}
await _hubContext.Clients.Group(inputDTO.RoomNum).ManagerRefresh(user, UId);
} }
/// <summary> /// <summary>
@ -319,17 +323,6 @@ namespace WGShare.API.Controllers.Frontend
await _hubContext.Clients.Group(roomNum).OperCamera(userInfo, UId); await _hubContext.Clients.Group(roomNum).OperCamera(userInfo, UId);
} }
///// <summary>
///// 同步视图
///// </summary>
///// <param name="type"></param>
///// <returns></returns>
//[HttpGet("sync-view")]
//public async Task ChangeView([FromQuery] string roomNum, [FromQuery] string type)
//{
// await _hubContext.Clients.Groups(roomNum).RefreshView(type);
//}
/// <summary> /// <summary>
/// 全员观看 /// 全员观看
/// </summary> /// </summary>
@ -403,20 +396,37 @@ namespace WGShare.API.Controllers.Frontend
}; };
using (var pipe = RedisHelper.Instance.StartPipe()) using (var pipe = RedisHelper.Instance.StartPipe())
{ {
//// 进房第一人,则设置全员看ta
//var script = $@"local exists = redis.call('HLEN', KEYS[1]) if (RoleId == RoleEnums.Admin)
// if exists == 0 then redis.call('HSET', KEYS[2], ARGV[1], ARGV[2]) end {
// return exists"; // 管理员进房如果没有全员看ta则设置
//pipe.Eval(script, [RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, roomNum), RedisKeyConstant.SessionManage.GetChannelShowUserKey(TenantId)], roomNum, UId); var script = @"local hashKey = KEYS[1]
local field = ARGV[1]
local value = ARGV[2]
if redis.call('HEXISTS', hashKey, field) == 0 then
redis.call('HSET', hashKey, field, value)
return 1
else
return 0
end";
pipe.Eval(script, [RedisKeyConstant.SessionManage.GetChannelShowUserKey(TenantId)], roomNum, UId);
}
// 记录频道得用户信息 // 记录频道得用户信息
pipe.HSet(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, roomNum), UId, userInfo); pipe.HSet(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, roomNum), UId, userInfo);
// 记录用户已参与频道 // 记录用户已参与频道
pipe.Set(RedisKeyConstant.SessionManage.GetUserJoinChannelKey(UId), roomNum); pipe.Set(RedisKeyConstant.SessionManage.GetUserJoinChannelKey(UId), roomNum);
pipe.EndPipe(); var results = pipe.EndPipe();
// 判断如果有全员看ta则通知
if (RoleId == RoleEnums.Admin && !results.IsNullOrEmpty() && results[0].ObjToInt() == 1)
await _hubContext.Clients.Group(roomNum).ShowUser(UId, UserName, UId, UserName);
} }
await _hubContext.Groups.AddToGroupAsync(ConnectionId, roomNum); await _hubContext.Groups.AddToGroupAsync(ConnectionId, roomNum);
await _hubContext.Clients.GroupExcept(roomNum, ConnectionId).UserJoined(userInfo); await _hubContext.Clients.GroupExcept(roomNum, ConnectionId).UserJoined(userInfo);
} }
/// <summary> /// <summary>
@ -440,7 +450,17 @@ namespace WGShare.API.Controllers.Frontend
pipe.HDel(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, roomNum), UId); pipe.HDel(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, roomNum), UId);
// 删除用户已参与频道 // 删除用户已参与频道
pipe.Del(RedisKeyConstant.SessionManage.GetUserJoinChannelKey(UId)); pipe.Del(RedisKeyConstant.SessionManage.GetUserJoinChannelKey(UId));
pipe.EndPipe(); var result = pipe.EndPipe();
if (!result.IsNullOrEmpty() && result[0].ObjToInt() != -1)
{
var users = RedisHelper.Instance.HVals<ChannelUserInfo>(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, roomNum));
var showUser = users.FirstOrDefault(x => x.RoleId == ((int)RoleEnums.Admin).ToString() || x.IsRoomManager);
if (showUser != null)
{
// 通知全员看ta
await _hubContext.Clients.Group(roomNum).ShowUser(showUser.UID, showUser.UserName, string.Empty, string.Empty);
}
}
} }
await _hubContext.Clients.GroupExcept(roomNum, ConnectionId).UserLeave(UId); await _hubContext.Clients.GroupExcept(roomNum, ConnectionId).UserLeave(UId);
@ -485,20 +505,44 @@ namespace WGShare.API.Controllers.Frontend
var channelUserInfos = RedisHelper.Instance.HVals<ChannelUserInfo>(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, roomNum)); var channelUserInfos = RedisHelper.Instance.HVals<ChannelUserInfo>(RedisKeyConstant.SessionManage.GetChannelUserKey(TenantId, roomNum));
var polledUserIds = RedisHelper.Instance.SMembers(RedisKeyConstant.Data.GetPolledUserId(TenantId, roomNum)); var polledUserIds = RedisHelper.Instance.SMembers(RedisKeyConstant.Data.GetPolledUserId(TenantId, roomNum));
// 排除已轮询的用户 // 使用 HashSet 提高查找效率
var userInfos = channelUserInfos.Where(x => !polledUserIds.Contains(x.UID) && x.RoleId != ((int)RoleEnums.Admin).ToString()).Take(count).ToList(); var polledUserIdsSet = new HashSet<string>(polledUserIds);
// 排除管理员和发言人
var candidates = channelUserInfos.Where(x => x.RoleId != ((int)RoleEnums.Admin).ToString() && !x.IsRoomManager);
// 使用 HashSet 提高查找效率
var userInfos = new List<ChannelUserInfo>();
var takenUids = new HashSet<string>();
// 从候选者中排除上次轮询的用户,获取指定数量的用户
foreach (var candidate in candidates)
{
if (userInfos.Count >= count)
break;
if (!polledUserIdsSet.Contains(candidate.UID))
{
userInfos.Add(candidate);
takenUids.Add(candidate.UID);
}
}
// 如果数量不足,则从未选择的候选者中取足
if (userInfos.Count < count) if (userInfos.Count < count)
{ {
// 数量不足,则从全部用户中取足 var remainingCandidates = candidates.Where(x => !takenUids.Contains(x.UID));
var takeCount = count - userInfos.Count < 0 ? 0 : count - userInfos.Count; userInfos.AddRange(remainingCandidates.Take(count - userInfos.Count));
userInfos.AddRange(channelUserInfos.Take(takeCount)); // 如果我们从所有用户中重新选择,清除之前的记录
// 删除记录,重新记录
RedisHelper.Instance.Del(RedisKeyConstant.Data.GetPolledUserId(TenantId, roomNum)); RedisHelper.Instance.Del(RedisKeyConstant.Data.GetPolledUserId(TenantId, roomNum));
} }
if (!userInfos.IsNullOrEmpty())
{
var watchUids = userInfos.Select(x => x.UID).ToArray(); var watchUids = userInfos.Select(x => x.UID).ToArray();
RedisHelper.Instance.SAdd(RedisKeyConstant.Data.GetPolledUserId(TenantId, roomNum), watchUids); RedisHelper.Instance.SAdd(RedisKeyConstant.Data.GetPolledUserId(TenantId, roomNum), watchUids);
_hubContext.Clients.Group(roomNum).Watch(watchUids); await _hubContext.Clients.Group(roomNum).Watch(watchUids);
}
return userInfos; return userInfos;
} }

View File

@ -102,8 +102,9 @@ namespace WGShare.API.Hubs
/// 管理员用户信息刷新 /// 管理员用户信息刷新
/// </summary> /// </summary>
/// <param name="user"></param> /// <param name="user"></param>
/// <param name="operUid"></param>
/// <returns></returns> /// <returns></returns>
Task ManagerRefresh(ChannelUserInfo user); Task ManagerRefresh(ChannelUserInfo user, string operUid);
/// <summary> /// <summary>
/// 强制登出 /// 强制登出
@ -123,6 +124,6 @@ namespace WGShare.API.Hubs
/// 接受监控用户 /// 接受监控用户
/// </summary> /// </summary>
/// <param name="watchUids"></param> /// <param name="watchUids"></param>
void Watch(string[] watchUids); Task Watch(string[] watchUids);
} }
} }

View File

@ -457,11 +457,12 @@
<param name="user"></param> <param name="user"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:WGShare.API.Hubs.IMessageClient.ManagerRefresh(WGShare.Domain.Entities.ChannelUserInfo)"> <member name="M:WGShare.API.Hubs.IMessageClient.ManagerRefresh(WGShare.Domain.Entities.ChannelUserInfo,System.String)">
<summary> <summary>
管理员用户信息刷新 管理员用户信息刷新
</summary> </summary>
<param name="user"></param> <param name="user"></param>
<param name="operUid"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:WGShare.API.Hubs.IMessageClient.ForceLogout(System.String)"> <member name="M:WGShare.API.Hubs.IMessageClient.ForceLogout(System.String)">
@ -478,6 +479,12 @@
<param name="uname"></param> <param name="uname"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:WGShare.API.Hubs.IMessageClient.Watch(System.String[])">
<summary>
接受监控用户
</summary>
<param name="watchUids"></param>
</member>
<member name="M:WGShare.API.Hubs.SessionManageHub.JoinChannel(System.String,System.Boolean,System.Boolean)"> <member name="M:WGShare.API.Hubs.SessionManageHub.JoinChannel(System.String,System.Boolean,System.Boolean)">
<summary> <summary>
加入频道 加入频道