예제 #1
0
        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);
        }
예제 #2
0
        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);
        }
예제 #3
0
        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));
        }
예제 #4
0
        /// <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);
        }
예제 #5
0
        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);
        }
예제 #6
0
        private async Task OnLeft(ConvCommand convMessage)
        {
            LCIMConversation conversation = await Client.GetOrQueryConversation(convMessage.Cid);

            // 从内存中清除对话
            Client.ConversationDict.Remove(conversation.Id);
            Client.OnKicked?.Invoke(conversation, convMessage.InitBy);
        }
예제 #7
0
        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);
        }
예제 #8
0
        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);
        }
예제 #9
0
        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);
        }
예제 #10
0
        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);
        }
예제 #11
0
        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);
        }
예제 #12
0
        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);
        }
예제 #13
0
        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);
        }
예제 #14
0
        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));
        }
예제 #15
0
        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;
        }
예제 #16
0
        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);
        }
예제 #17
0
        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);
        }
예제 #18
0
        /// <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);
        }
예제 #19
0
        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));
        }
예제 #20
0
        /// <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);
        }
예제 #21
0
        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);
        }
예제 #22
0
        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
            });
        }
예제 #23
0
        /// <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);
        }
예제 #24
0
        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);
        }
예제 #25
0
        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());
        }
예제 #26
0
        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;
            }
        }
예제 #27
0
        private async Task OnUnblocked(ConvCommand convMessage)
        {
            LCIMConversation conversation = await Client.GetOrQueryConversation(convMessage.Cid);

            Client.OnUnblocked?.Invoke(conversation, convMessage.InitBy);
        }