internal async Task <List <LCIMTemporaryConversation> > GetTemporaryConversations(IEnumerable <string> convIds) { if (convIds == null || convIds.Count() == 0) { return(null); } ConvCommand convMessage = new ConvCommand(); convMessage.TempConvIds.AddRange(convIds); GenericCommand request = NewCommand(CommandType.Conv, OpType.Query); request.ConvMessage = convMessage; GenericCommand response = await Connection.SendRequest(request); JsonObjectMessage results = response.ConvMessage.Results; List <object> convs = JsonConvert.DeserializeObject <List <object> >(results.Data, LCJsonConverter.Default); List <LCIMTemporaryConversation> convList = convs.Select(item => { LCIMTemporaryConversation temporaryConversation = new LCIMTemporaryConversation(Client); temporaryConversation.MergeFrom(item as Dictionary <string, object>); return(temporaryConversation); }).ToList(); return(convList); }
internal async Task <Dictionary <string, object> > UpdateInfo(string convId, Dictionary <string, object> attributes) { ConvCommand conv = new ConvCommand { Cid = convId, }; conv.Attr = new JsonObjectMessage { Data = JsonConvert.SerializeObject(attributes) }; GenericCommand request = NewCommand(CommandType.Conv, OpType.Update); request.ConvMessage = conv; GenericCommand response = await Connection.SendRequest(request); JsonObjectMessage attr = response.ConvMessage.AttrModified; // 更新自定义属性 if (attr != null) { Dictionary <string, object> updatedAttr = JsonConvert.DeserializeObject <Dictionary <string, object> >(attr.Data); return(updatedAttr); } return(null); }
internal async Task <LCIMPartiallySuccessResult> RemoveMembers(string convId, IEnumerable <string> removeIds) { ConvCommand conv = new ConvCommand { Cid = convId, }; conv.M.AddRange(removeIds); // 签名参数 if (Client.SignatureFactory != null) { LCIMSignature signature = await Client.SignatureFactory.CreateConversationSignature(convId, Client.Id, removeIds, LCIMSignatureAction.Kick); conv.S = signature.Signature; conv.T = signature.Timestamp; conv.N = signature.Nonce; } GenericCommand request = NewCommand(CommandType.Conv, OpType.Remove); request.ConvMessage = conv; GenericCommand response = await Connection.SendRequest(request); List <string> allowedIds = response.ConvMessage.AllowedPids.ToList(); List <ErrorCommand> errors = response.ConvMessage.FailedPids.ToList(); return(NewPartiallySuccessResult(allowedIds, errors)); }
/// <summary> /// 创建会话 /// </summary> /// <returns>The conversation async.</returns> /// <param name="clientId">Client identifier.</param> /// <param name="memberIds">Member identifiers.</param> internal Task <AVIMConversation> CreateConversationAsync(string clientId, List <string> memberIds) { var tcs = new TaskCompletionSource <AVIMConversation>(); var createConv = new ConvCommand { Unique = true, }; createConv.M.AddRange(memberIds); var cmd = commandFactory.NewRequest(clientId, CommandType.Conv, OpType.Start); cmd.convMessage = createConv; SendRequest(cmd).ContinueWith(t => { if (t.IsFaulted) { throw t.Exception.InnerException; } var res = t.Result; var createdRes = res.convMessage; // TODO 查询会话对象 return(QueryConversationAsync(clientId, createdRes.Cid)); }).Unwrap().ContinueWith(t => { if (t.IsFaulted) { tcs.SetException(t.Exception.InnerException); } else { tcs.SetResult(t.Result); } }); return(tcs.Task); }
private async Task OnMembersUnblocked(ConvCommand convMessage) { LCIMConversation conversation = await Client.GetOrQueryConversation(convMessage.Cid); ReadOnlyCollection <string> unblockedMemberIds = convMessage.M.ToList().AsReadOnly(); Client.OnMembersUnblocked?.Invoke(conversation, unblockedMemberIds, convMessage.InitBy); }
private async Task OnLeft(ConvCommand convMessage) { LCIMConversation conversation = await Client.GetOrQueryConversation(convMessage.Cid); // 从内存中清除对话 Client.ConversationDict.Remove(conversation.Id); Client.OnKicked?.Invoke(conversation, convMessage.InitBy); }
private async Task OnMemberInfoChanged(ConvCommand conv) { LCIMConversation conversation = await Client.GetOrQueryConversation(conv.Cid); ConvMemberInfo memberInfo = conv.Info; Client.OnMemberInfoUpdated?.Invoke(conversation, memberInfo.Pid, memberInfo.Role, conv.InitBy); }
private async Task OnMembersUnmuted(ConvCommand convMessage) { LCIMConversation conversation = await Client.GetOrQueryConversation(convMessage.Cid); ReadOnlyCollection <string> unmutedMemberIds = new ReadOnlyCollection <string>(convMessage.M); conversation.mutedIds.RemoveWhere(id => unmutedMemberIds.Contains(id)); Client.OnMembersUnmuted?.Invoke(conversation, unmutedMemberIds, convMessage.InitBy); }
private async Task OnMembersMuted(ConvCommand convMessage) { LCIMConversation conversation = await Client.GetOrQueryConversation(convMessage.Cid); ReadOnlyCollection <string> mutedMemberIds = new ReadOnlyCollection <string>(convMessage.M); conversation.mutedIds.UnionWith(mutedMemberIds); Client.OnMembersMuted?.Invoke(conversation, mutedMemberIds, convMessage.InitBy); }
private async Task OnMemberLeft(ConvCommand convMessage) { LCIMConversation conversation = await Client.GetOrQueryConversation(convMessage.Cid); ReadOnlyCollection <string> leftIdList = new ReadOnlyCollection <string>(convMessage.M); conversation.ids.RemoveWhere(item => leftIdList.Contains(item)); Client.OnMembersLeft?.Invoke(conversation, leftIdList, convMessage.InitBy); }
internal async Task Unmute(string convId) { ConvCommand conv = new ConvCommand { Cid = convId }; GenericCommand request = NewCommand(CommandType.Conv, OpType.Unmute); request.ConvMessage = conv; await Connection.SendRequest(request); }
internal async Task <int> GetMembersCount(string convId) { ConvCommand conv = new ConvCommand { Cid = convId, }; GenericCommand command = NewCommand(CommandType.Conv, OpType.Count); command.ConvMessage = conv; GenericCommand response = await Connection.SendRequest(command); return(response.ConvMessage.Count); }
private async Task OnPropertiesUpdated(ConvCommand conv) { LCIMConversation conversation = await Client.GetOrQueryConversation(conv.Cid); Dictionary <string, object> updatedAttr = JsonConvert.DeserializeObject <Dictionary <string, object> >(conv.AttrModified.Data, LCJsonConverter.Default); // 更新内存数据 conversation.MergeInfo(updatedAttr); Client.OnConversationInfoUpdated?.Invoke(conversation, new ReadOnlyDictionary <string, object>(updatedAttr), conv.InitBy); }
internal async Task <LCIMPartiallySuccessResult> UnmuteMembers(string convId, IEnumerable <string> clientIds) { ConvCommand conv = new ConvCommand { Cid = convId }; conv.M.AddRange(clientIds); GenericCommand request = NewCommand(CommandType.Conv, OpType.RemoveShutup); request.ConvMessage = conv; GenericCommand response = await Connection.SendRequest(request); return(NewPartiallySuccessResult(response.ConvMessage.AllowedPids, response.ConvMessage.FailedPids)); }
internal async Task FetchReciptTimestamp(string convId) { ConvCommand convCommand = new ConvCommand { Cid = convId }; GenericCommand request = NewCommand(CommandType.Conv, OpType.MaxRead); request.ConvMessage = convCommand; GenericCommand response = await Connection.SendRequest(request); convCommand = response.ConvMessage; LCIMConversation conversation = await Client.GetOrQueryConversation(convCommand.Cid); conversation.LastDeliveredTimestamp = convCommand.MaxAckTimestamp; conversation.LastReadTimestamp = convCommand.MaxReadTimestamp; }
internal async Task <ReadOnlyCollection <string> > GetOnlineMembers(string convId, int limit) { ConvCommand conv = new ConvCommand { Cid = convId, Limit = limit }; GenericCommand request = NewCommand(CommandType.Conv, OpType.Members); request.ConvMessage = conv; GenericCommand response = await Connection.SendRequest(request); ReadOnlyCollection <string> members = response.ConvMessage.M .ToList().AsReadOnly(); return(members); }
internal async Task UpdateMemberRole(string convId, string memberId, string role) { ConvCommand conv = new ConvCommand { Cid = convId, TargetClientId = memberId, Info = new ConvMemberInfo { Pid = memberId, Role = role } }; GenericCommand request = NewCommand(CommandType.Conv, OpType.MemberInfoUpdate); request.ConvMessage = conv; GenericCommand response = await Connection.SendRequest(request); }
/// <summary> /// 查询会话 /// </summary> /// <returns>The conversation async.</returns> /// <param name="clientId">Client identifier.</param> /// <param name="convId">Conv identifier.</param> internal Task <AVIMConversation> QueryConversationAsync(string clientId, string convId) { var tcs = new TaskCompletionSource <AVIMConversation>(); var where = new Dictionary <string, string> { { "objectId", convId } }; var queryConv = new ConvCommand { Where = new JsonObjectMessage { Data = JsonConvert.SerializeObject(where), }, }; var cmd = commandFactory.NewRequest(clientId, CommandType.Conv, OpType.Query); cmd.convMessage = queryConv; SendRequest(cmd).ContinueWith(t => { if (t.IsFaulted) { tcs.SetException(t.Exception.InnerException); } else { var res = t.Result; var queriedRes = res.convMessage; // TODO 实例化 AVIMConversation 对象 var convs = JsonConvert.DeserializeObject <List <Dictionary <string, object> > >(queriedRes.Results.Data); var rawData = convs[0]; var conv = new AVIMConversation { convId = convId, rawData = rawData }; // 将会话对象添加至对应的用户内存中 AVRealtime.Context.Post(() => { if (idToClient.TryGetValue(clientId, out var client)) { conv.Client = client; client.UpdateConversation(conv); } tcs.SetResult(conv); }); } }); return(tcs.Task); }
internal async Task <LCIMPartiallySuccessResult> MuteMembers(string convId, IEnumerable <string> clientIds) { if (clientIds == null || clientIds.Count() == 0) { throw new ArgumentNullException(nameof(clientIds)); } ConvCommand conv = new ConvCommand { Cid = convId }; conv.M.AddRange(clientIds); GenericCommand request = NewCommand(CommandType.Conv, OpType.AddShutup); request.ConvMessage = conv; GenericCommand response = await Connection.SendRequest(request); return(NewPartiallySuccessResult(response.ConvMessage.AllowedPids, response.ConvMessage.FailedPids)); }
/// <summary> /// 退出会话 /// </summary> /// <returns>The conversation async.</returns> /// <param name="convId">Conv identifier.</param> /// <param name="memberIdList">Member identifier list.</param> internal Task QuitConversationAsync(string clientId, string convId, List <string> memberIdList) { var tcs = new TaskCompletionSource <bool>(); if (memberIdList == null) { tcs.SetException(new ArgumentNullException()); } else { var quitConv = new ConvCommand { Cid = convId, }; quitConv.M.AddRange(memberIdList); var cmd = commandFactory.NewRequest(clientId, CommandType.Conv, OpType.Remove); cmd.convMessage = quitConv; SendRequest(cmd).ContinueWith(t => { if (t.IsFaulted) { tcs.SetException(t.Exception); return; } var res = t.Result; var quitRes = res.convMessage; // 判断是否是自己成功离开 if (quitRes.allowedPids.Contains(clientId)) { AVRealtime.Context.Post(() => { if (idToClient.TryGetValue(clientId, out var client)) { client.RemoveConversation(convId); } tcs.SetResult(true); }); } else { tcs.SetResult(true); } }); } return(tcs.Task); }
internal async Task <bool> CheckSubscription(string convId) { ConvCommand conv = new ConvCommand(); conv.Cids.Add(convId); GenericCommand request = NewCommand(CommandType.Conv, OpType.IsMember); request.ConvMessage = conv; GenericCommand response = await Connection.SendRequest(request); JsonObjectMessage jsonObj = response.ConvMessage.Results; Dictionary <string, object> result = JsonConvert.DeserializeObject <Dictionary <string, object> >(jsonObj.Data); if (result.TryGetValue(convId, out object obj)) { return((bool)obj); } return(false); }
internal async Task <LCIMPageResult> QueryMutedMembers(string convId, int limit = 10, string next = null) { ConvCommand conv = new ConvCommand { Cid = convId, Limit = limit }; if (next != null) { conv.Next = next; } GenericCommand request = NewCommand(CommandType.Conv, OpType.QueryShutup); request.ConvMessage = conv; GenericCommand response = await Connection.SendRequest(request); return(new LCIMPageResult { Results = new ReadOnlyCollection <string>(response.ConvMessage.M), Next = response.ConvMessage.Next }); }
/// <summary> /// 加入会话 /// </summary> /// <returns>The conversation async.</returns> /// <param name="clientId">Client identifier.</param> /// <param name="convId">Conv identifier.</param> internal Task <AVIMConversation> JoinConversationAsync(string clientId, string convId) { var tcs = new TaskCompletionSource <AVIMConversation>(); var joinConv = new ConvCommand { Cid = convId, }; joinConv.M.Add(clientId); var cmd = commandFactory.NewRequest(clientId, CommandType.Conv, OpType.Add); cmd.convMessage = joinConv; SendRequest(cmd).ContinueWith(t => { if (t.IsFaulted) { throw t.Exception.InnerException; } var res = t.Result; var joinedRes = res.convMessage; return(QueryConversationAsync(clientId, joinedRes.Cid)); }).Unwrap().ContinueWith(t => { tcs.SetResult(t.Result); }); return(tcs.Task); }
internal async Task <LCIMConversation> CreateConv( IEnumerable <string> members = null, string name = null, bool transient = false, bool unique = true, bool temporary = false, int temporaryTtl = 86400, Dictionary <string, object> properties = null) { GenericCommand request = NewCommand(CommandType.Conv, OpType.Start); ConvCommand conv = new ConvCommand { Transient = transient, Unique = unique, }; if (members != null) { conv.M.AddRange(members); } if (temporary) { conv.TempConv = temporary; conv.TempConvTTL = temporaryTtl; } Dictionary <string, object> attrs = new Dictionary <string, object>(); if (!string.IsNullOrEmpty(name)) { attrs["name"] = name; } if (properties != null) { attrs = properties.Union(attrs.Where(kv => !properties.ContainsKey(kv.Key))) .ToDictionary(k => k.Key, v => v.Value); } conv.Attr = new JsonObjectMessage { Data = JsonConvert.SerializeObject(LCEncoder.Encode(attrs)) }; if (Client.SignatureFactory != null) { LCIMSignature signature = await Client.SignatureFactory.CreateStartConversationSignature(Client.Id, members); conv.S = signature.Signature; conv.T = signature.Timestamp; conv.N = signature.Nonce; } request.ConvMessage = conv; GenericCommand response = await Connection.SendRequest(request); string convId = response.ConvMessage.Cid; if (!Client.ConversationDict.TryGetValue(convId, out LCIMConversation conversation)) { if (transient) { conversation = new LCIMChatRoom(Client); } else if (temporary) { conversation = new LCIMTemporaryConversation(Client); } else if (properties != null && properties.ContainsKey("system")) { conversation = new LCIMServiceConversation(Client); } else { conversation = new LCIMConversation(Client); } Client.ConversationDict[convId] = conversation; } // 合并请求数据 conversation.Id = convId; conversation.Unique = unique; conversation.UniqueId = response.ConvMessage.UniqueId; conversation.Name = name; conversation.CreatorId = Client.Id; conversation.ids = members != null ? new HashSet <string>(members) : new HashSet <string>(); // 将自己加入 conversation.ids.Add(Client.Id); conversation.CreatedAt = DateTime.Parse(response.ConvMessage.Cdate); conversation.UpdatedAt = conversation.CreatedAt; return(conversation); }
internal async Task <ReadOnlyCollection <LCIMConversation> > Find(LCIMConversationQuery query) { GenericCommand command = new GenericCommand { Cmd = CommandType.Conv, Op = OpType.Query, AppId = LCCore.AppId, PeerId = Client.Id, }; ConvCommand convMessage = new ConvCommand(); string where = query.Condition.BuildWhere(); if (!string.IsNullOrEmpty(where)) { try { convMessage.Where = new JsonObjectMessage { Data = where }; } catch (Exception e) { LCLogger.Error(e); } } int flag = 0; if (query.Compact) { flag += LCIMConversationQuery.CompactFlag; } if (query.WithLastMessageRefreshed) { flag += LCIMConversationQuery.WithLastMessageFlag; } if (flag > 0) { convMessage.Flag = flag; } convMessage.Skip = query.Condition.Skip; convMessage.Limit = query.Condition.Limit; string orders = query.Condition.BuildOrders(); if (!string.IsNullOrEmpty(orders)) { convMessage.Sort = orders; } command.ConvMessage = convMessage; GenericCommand response = await Connection.SendRequest(command); JsonObjectMessage results = response.ConvMessage.Results; List <object> convs = JsonConvert.DeserializeObject <List <object> >(results.Data, LCJsonConverter.Default); return(convs.Select(item => { Dictionary <string, object> conv = item as Dictionary <string, object>; string convId = conv["objectId"] as string; if (!Client.ConversationDict.TryGetValue(convId, out LCIMConversation conversation)) { // 解析是哪种类型的对话 if (conv.TryGetValue("tr", out object transient) && (bool)transient == true) { conversation = new LCIMChatRoom(Client); } else if (conv.ContainsKey("tempConv") && conv.ContainsKey("tempConvTTL")) { conversation = new LCIMTemporaryConversation(Client); } else if (conv.TryGetValue("sys", out object sys) && (bool)sys == true) { conversation = new LCIMServiceConversation(Client); } else { conversation = new LCIMConversation(Client); } Client.ConversationDict[convId] = conversation; } conversation.MergeFrom(conv); return conversation; }).ToList().AsReadOnly()); }
private async Task OnConversation(GenericCommand notification) { ConvCommand convMessage = notification.ConvMessage; switch (notification.Op) { case OpType.Joined: await OnJoined(convMessage); break; case OpType.MembersJoined: await OnMembersJoined(convMessage); break; case OpType.Left: await OnLeft(convMessage); break; case OpType.MembersLeft: await OnMemberLeft(convMessage); break; case OpType.Blocked: await OnBlocked(convMessage); break; case OpType.Unblocked: await OnUnblocked(convMessage); break; case OpType.MembersBlocked: await OnMembersBlocked(convMessage); break; case OpType.MembersUnblocked: await OnMembersUnblocked(convMessage); break; case OpType.Shutuped: await OnMuted(convMessage); break; case OpType.Unshutuped: await OnUnmuted(convMessage); break; case OpType.MembersShutuped: await OnMembersMuted(convMessage); break; case OpType.MembersUnshutuped: await OnMembersUnmuted(convMessage); break; case OpType.Updated: await OnPropertiesUpdated(convMessage); break; case OpType.MemberInfoChanged: await OnMemberInfoChanged(convMessage); break; default: break; } }
private async Task OnUnblocked(ConvCommand convMessage) { LCIMConversation conversation = await Client.GetOrQueryConversation(convMessage.Cid); Client.OnUnblocked?.Invoke(conversation, convMessage.InitBy); }