예제 #1
0
        public async Task Custom()
        {
            TaskCompletionSource <object> tcs = new TaskCompletionSource <object>();

            // 注册自定义类型消息
            LCIMTypedMessage.Register(EmojiMessage.EmojiMessageType,
                                      () => new EmojiMessage());
            m2.OnMessage = (conv, msg) => {
                Assert.True(msg is EmojiMessage);
                EmojiMessage emojiMsg = msg as EmojiMessage;
                Assert.AreEqual(emojiMsg.Ecode, "#0123");
                tcs.SetResult(null);
            };
            EmojiMessage emojiMessage = new EmojiMessage {
                Ecode = "#0123"
            };
            await conversation.Send(emojiMessage);

            await tcs.Task;
        }
예제 #2
0
        private async Task OnMessaage(GenericCommand notification)
        {
            DirectCommand direct = notification.DirectMessage;
            // 反序列化消息
            LCIMMessage message;

            if (direct.HasBinaryMsg)
            {
                // 二进制消息
                byte[] bytes = direct.BinaryMsg.ToByteArray();
                message = LCIMBinaryMessage.Deserialize(bytes);
            }
            else
            {
                // 类型消息
                message = LCIMTypedMessage.Deserialize(direct.Msg);
            }
            // 填充消息数据
            message.ConversationId = direct.Cid;
            message.Id             = direct.Id;
            message.FromClientId   = direct.FromPeerId;
            message.SentTimestamp  = direct.Timestamp;
            message.MentionAll     = direct.MentionAll;
            message.MentionIdList  = direct.MentionPids.ToList();
            message.Mentioned      = message.MentionAll ||
                                     message.MentionIdList.Contains(Client.Id);
            message.PatchedTimestamp = direct.PatchTimestamp;
            message.IsTransient      = direct.Transient;
            // 获取对话
            LCIMConversation conversation = await Client.GetOrQueryConversation(direct.Cid);

            conversation.Unread++;
            conversation.LastMessage = message;
            // 通知服务端已接收
            if (!(conversation is LCIMChatRoom) && !message.IsTransient)
            {
                // 只有非暂态消息才需要发送 ack
                _ = Ack(message.ConversationId, message.Id);
            }
            Client.OnMessage?.Invoke(conversation, message);
        }
예제 #3
0
        public async Task Attributes()
        {
            TaskCompletionSource <object> tcs = new TaskCompletionSource <object>();

            m2.OnMessage = (conv, msg) => {
                Assert.True(msg is LCIMTypedMessage);
                LCIMTypedMessage typedMsg = msg as LCIMTypedMessage;
                Assert.AreEqual(typedMsg["k1"], 123);
                Assert.True((bool)typedMsg["k2"]);
                Assert.AreEqual(typedMsg["k3"], "code");
                tcs.SetResult(null);
            };
            LCIMTextMessage textMsg = new LCIMTextMessage("hi");

            textMsg["k1"] = 123;
            textMsg["k2"] = true;
            textMsg["k3"] = "code";
            await conversation.Send(textMsg);

            await tcs.Task;
        }
예제 #4
0
        private async Task OnUnread(GenericCommand notification)
        {
            UnreadCommand unread = notification.UnreadMessage;

            IEnumerable <string> convIds = unread.Convs
                                           .Select(conv => conv.Cid);
            Dictionary <string, LCIMConversation> conversationDict = (await Client.GetConversationList(convIds))
                                                                     .ToDictionary(item => item.Id);
            ReadOnlyCollection <LCIMConversation> conversations = unread.Convs.Select(conv => {
                // 设置对话中的未读数据
                LCIMConversation conversation = conversationDict[conv.Cid];
                conversation.Unread           = conv.Unread;
                if (conv.HasData || conv.HasBinaryMsg)
                {
                    // 如果有消息,则反序列化
                    LCIMMessage message = null;
                    if (conv.HasBinaryMsg)
                    {
                        // 二进制消息
                        byte[] bytes = conv.BinaryMsg.ToByteArray();
                        message      = LCIMBinaryMessage.Deserialize(bytes);
                    }
                    else
                    {
                        // 类型消息
                        message = LCIMTypedMessage.Deserialize(conv.Data);
                    }
                    // 填充消息数据
                    message.ConversationId   = conv.Cid;
                    message.Id               = conv.Mid;
                    message.FromClientId     = conv.From;
                    message.SentTimestamp    = conv.Timestamp;
                    message.Mentioned        = conv.Mentioned;
                    conversation.LastMessage = message;
                }
                return(conversation);
            }).ToList().AsReadOnly();

            Client.OnUnreadMessagesCountUpdated?.Invoke(conversations);
        }
예제 #5
0
        private async Task OnMessagePatched(GenericCommand notification)
        {
            PatchCommand patchMessage = notification.PatchMessage;

            foreach (PatchItem patch in patchMessage.Patches)
            {
                // 获取对话
                LCIMConversation conversation = await Client.GetOrQueryConversation(patch.Cid);

                LCIMMessage message;
                if (patch.HasBinaryMsg)
                {
                    byte[] bytes = patch.BinaryMsg.ToByteArray();
                    message = LCIMBinaryMessage.Deserialize(bytes);
                }
                else
                {
                    message = LCIMTypedMessage.Deserialize(patch.Data);
                }
                message.ConversationId   = patch.Cid;
                message.Id               = patch.Mid;
                message.FromClientId     = patch.From;
                message.SentTimestamp    = patch.Timestamp;
                message.PatchedTimestamp = patch.PatchTimestamp;
                if (message is LCIMRecalledMessage recalledMessage)
                {
                    // 消息撤回
                    Client.OnMessageRecalled?.Invoke(conversation, recalledMessage);
                }
                else
                {
                    // 消息修改
                    Client.OnMessageUpdated?.Invoke(conversation, message);
                }
            }
        }
예제 #6
0
 internal void MergeFrom(Dictionary <string, object> conv)
 {
     if (conv.TryGetValue("objectId", out object idObj))
     {
         Id = idObj as string;
     }
     if (conv.TryGetValue("name", out object nameObj))
     {
         Name = nameObj as string;
     }
     if (conv.TryGetValue("unique", out object uniqueObj))
     {
         Unique = (bool)uniqueObj;
     }
     if (conv.TryGetValue("uniqueId", out object uniqueIdObj))
     {
         UniqueId = uniqueIdObj as string;
     }
     if (conv.TryGetValue("createdAt", out object createdAtObj))
     {
         CreatedAt = DateTime.Parse(createdAtObj.ToString());
     }
     if (conv.TryGetValue("updatedAt", out object updatedAtObj))
     {
         UpdatedAt = DateTime.Parse(updatedAtObj.ToString());
     }
     if (conv.TryGetValue("c", out object co))
     {
         CreatorId = co as string;
     }
     if (conv.TryGetValue("m", out object mo))
     {
         IEnumerable <string> ids = (mo as IList <object>).Cast <string>();
         this.ids = new HashSet <string>(ids);
     }
     if (conv.TryGetValue("mu", out object muo))
     {
         IEnumerable <string> ids = (muo as IList <object>).Cast <string>();
         mutedIds = new HashSet <string>(ids);
     }
     if (conv.TryGetValue("msg", out object msgo))
     {
         if (conv.TryGetValue("bin", out object bino))
         {
             string msg = msgo as string;
             bool   bin = (bool)bino;
             if (bin)
             {
                 byte[] bytes = Convert.FromBase64String(msg);
                 LastMessage = LCIMBinaryMessage.Deserialize(bytes);
             }
             else
             {
                 LastMessage = LCIMTypedMessage.Deserialize(msg);
             }
         }
         LastMessage.ConversationId = Id;
         if (conv.TryGetValue("msg_mid", out object msgId))
         {
             LastMessage.Id = msgId as string;
         }
         if (conv.TryGetValue("msg_from", out object msgFrom))
         {
             LastMessage.FromClientId = msgFrom as string;
         }
         if (conv.TryGetValue("msg_timestamp", out object timestamp))
         {
             LastMessage.SentTimestamp = (long)timestamp;
         }
     }
 }
예제 #7
0
        internal async Task <ReadOnlyCollection <LCIMMessage> > QueryMessages(string convId,
                                                                              LCIMMessageQueryEndpoint start      = null,
                                                                              LCIMMessageQueryEndpoint end        = null,
                                                                              LCIMMessageQueryDirection direction = LCIMMessageQueryDirection.NewToOld,
                                                                              int limit       = 20,
                                                                              int messageType = 0)
        {
            LogsCommand logs = new LogsCommand {
                Cid = convId
            };

            if (start != null)
            {
                logs.T         = start.SentTimestamp;
                logs.Mid       = start.MessageId;
                logs.TIncluded = start.IsClosed;
            }
            if (end != null)
            {
                logs.Tt         = end.SentTimestamp;
                logs.Tmid       = end.MessageId;
                logs.TtIncluded = end.IsClosed;
            }
            logs.Direction = direction == LCIMMessageQueryDirection.NewToOld ?
                             LogsCommand.Types.QueryDirection.Old : LogsCommand.Types.QueryDirection.New;
            logs.Limit = limit;
            if (messageType != 0)
            {
                logs.Lctype = messageType;
            }
            GenericCommand request = NewCommand(CommandType.Logs, OpType.Open);

            request.LogsMessage = logs;
            GenericCommand response = await Connection.SendRequest(request);

            // 反序列化聊天记录
            return(response.LogsMessage.Logs.Select(item => {
                LCIMMessage message;
                if (item.Bin)
                {
                    // 二进制消息
                    byte[] bytes = Convert.FromBase64String(item.Data);
                    message = LCIMBinaryMessage.Deserialize(bytes);
                }
                else
                {
                    // 类型消息
                    message = LCIMTypedMessage.Deserialize(item.Data);
                }
                message.ConversationId = convId;
                message.Id = item.MsgId;
                message.FromClientId = item.From;
                message.SentTimestamp = item.Timestamp;
                message.DeliveredTimestamp = item.AckAt;
                message.ReadTimestamp = item.ReadAt;
                message.PatchedTimestamp = item.PatchTimestamp;
                message.MentionAll = item.MentionAll;
                message.MentionIdList = item.MentionPids.ToList();
                message.Mentioned = message.MentionAll ||
                                    message.MentionIdList.Contains(Client.Id);
                return message;
            }).ToList().AsReadOnly());
        }