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; }
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); }
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; }
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); }
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); } } }
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; } } }
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()); }