chore: 梳理 Message 序列化

oneRain 2020-03-27 17:30:18 +08:00
parent a1376a346d
commit 8d059f106a
8 changed files with 47 additions and 83 deletions

View File

@ -384,10 +384,10 @@ namespace LeanCloud.Realtime {
CreatorId = co as string; CreatorId = co as string;
} }
if (conv.TryGetValue("m", out object mo)) { if (conv.TryGetValue("m", out object mo)) {
ids = new HashSet<string>(mo as List<string>); ids = new HashSet<string>((mo as IList<object>).Cast<string>());
} }
if (conv.TryGetValue("mu", out object muo)) { if (conv.TryGetValue("mu", out object muo)) {
mutedIds = new HashSet<string>(muo as List<string>); mutedIds = new HashSet<string>((muo as IList<object>).Cast<string>());
} }
} }

View File

@ -462,6 +462,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
conversation = new LCIMConversation(Client); conversation = new LCIMConversation(Client);
Client.ConversationDict[convId] = conversation; Client.ConversationDict[convId] = conversation;
} }
conversation.MergeFrom(conv); conversation.MergeFrom(conv);
return conversation; return conversation;
}).ToList().AsReadOnly(); }).ToList().AsReadOnly();

View File

@ -85,8 +85,8 @@ namespace LeanCloud.Realtime.Internal.Controller {
} else if (newMessage is LCIMBinaryMessage binaryMessage) { } else if (newMessage is LCIMBinaryMessage binaryMessage) {
item.BinaryMsg = ByteString.CopyFrom(binaryMessage.Data); item.BinaryMsg = ByteString.CopyFrom(binaryMessage.Data);
} }
if (newMessage.MentionList != null) { if (newMessage.MentionIdList != null) {
item.MentionPids.AddRange(newMessage.MentionList); item.MentionPids.AddRange(newMessage.MentionIdList);
} }
if (newMessage.MentionAll) { if (newMessage.MentionAll) {
item.MentionAll = newMessage.MentionAll; item.MentionAll = newMessage.MentionAll;
@ -146,43 +146,23 @@ namespace LeanCloud.Realtime.Internal.Controller {
internal override async Task OnNotification(GenericCommand notification) { internal override async Task OnNotification(GenericCommand notification) {
DirectCommand direct = notification.DirectMessage; DirectCommand direct = notification.DirectMessage;
LCIMMessage message = null; LCIMMessage message;
if (direct.HasBinaryMsg) { if (direct.HasBinaryMsg) {
// 二进制消息 // 二进制消息
byte[] bytes = direct.BinaryMsg.ToByteArray(); byte[] bytes = direct.BinaryMsg.ToByteArray();
message = new LCIMBinaryMessage(bytes); message = LCIMBinaryMessage.Deserialize(bytes);
} else { } else {
// 文本消息 // 类型消息
string messageData = direct.Msg; message = LCIMTypedMessage.Deserialize(direct.Msg);
Dictionary<string, object> msgData = JsonConvert.DeserializeObject<Dictionary<string, object>>(messageData,
new LCJsonConverter());
int msgType = (int)msgData["_lctype"];
switch (msgType) {
case -1:
message = new LCIMTextMessage();
break;
case -2:
message = new LCIMImageMessage();
break;
case -3:
message = new LCIMAudioMessage();
break;
case -4:
message = new LCIMVideoMessage();
break;
case -5:
message = new LCIMLocationMessage();
break;
case -6:
message = new LCIMFileMessage();
break;
default:
break;
}
message.Decode(direct);
} }
// 填充消息数据
message.ConversationId = direct.Cid;
message.Id = direct.Id;
message.FromClientId = direct.FromPeerId;
message.SentTimestamp = direct.Timestamp;
// 获取对话 // 获取对话
LCIMConversation conversation = await Client.GetOrQueryConversation(direct.Cid); LCIMConversation conversation = await Client.GetOrQueryConversation(direct.Cid);
conversation.LastMessage = message;
Client.OnMessage?.Invoke(conversation, message); Client.OnMessage?.Invoke(conversation, message);
} }

View File

@ -2,9 +2,7 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using Newtonsoft.Json;
using LeanCloud.Realtime.Protocol; using LeanCloud.Realtime.Protocol;
using LeanCloud.Storage.Internal;
namespace LeanCloud.Realtime.Internal.Controller { namespace LeanCloud.Realtime.Internal.Controller {
internal class LCIMUnreadController : LCIMController { internal class LCIMUnreadController : LCIMController {
@ -22,35 +20,20 @@ namespace LeanCloud.Realtime.Internal.Controller {
Dictionary<string, LCIMConversation> conversationDict = (await Client.GetConversationList(convIds)) Dictionary<string, LCIMConversation> conversationDict = (await Client.GetConversationList(convIds))
.ToDictionary(item => item.Id); .ToDictionary(item => item.Id);
ReadOnlyCollection<LCIMConversation> conversations = unread.Convs.Select(conv => { ReadOnlyCollection<LCIMConversation> conversations = unread.Convs.Select(conv => {
// 设置对话中的未读数据
LCIMConversation conversation = conversationDict[conv.Cid]; LCIMConversation conversation = conversationDict[conv.Cid];
conversation.Unread = conv.Unread; conversation.Unread = conv.Unread;
// 解析最后一条消息
Dictionary<string, object> msgData = JsonConvert.DeserializeObject<Dictionary<string, object>>(conv.Data,
new LCJsonConverter());
int msgType = (int)msgData["_lctype"];
LCIMMessage message = null; LCIMMessage message = null;
switch (msgType) { if (conv.HasBinaryMsg) {
case -1: // 二进制消息
message = new LCIMTextMessage(); byte[] bytes = conv.BinaryMsg.ToByteArray();
break; message = LCIMBinaryMessage.Deserialize(bytes);
case -2: } else {
message = new LCIMImageMessage(); // 类型消息
break; message = LCIMTypedMessage.Deserialize(conv.Data);
case -3:
message = new LCIMAudioMessage();
break;
case -4:
message = new LCIMVideoMessage();
break;
case -5:
message = new LCIMLocationMessage();
break;
case -6:
message = new LCIMFileMessage();
break;
default:
break;
} }
// 填充消息数据
message.ConversationId = conv.Cid; message.ConversationId = conv.Cid;
message.Id = conv.Mid; message.Id = conv.Mid;
message.FromClientId = conv.From; message.FromClientId = conv.From;

View File

@ -10,5 +10,9 @@ namespace LeanCloud.Realtime {
public LCIMBinaryMessage(byte[] data) { public LCIMBinaryMessage(byte[] data) {
Data = data; Data = data;
} }
internal static LCIMBinaryMessage Deserialize(byte[] bytes) {
return new LCIMBinaryMessage(bytes);
}
} }
} }

View File

@ -1,4 +1,5 @@
using System; using System;
using System.Linq;
using System.Collections.Generic; using System.Collections.Generic;
using LeanCloud.Realtime.Protocol; using LeanCloud.Realtime.Protocol;
@ -67,7 +68,7 @@ namespace LeanCloud.Realtime {
} }
} }
public List<string> MentionList { public List<string> MentionIdList {
get; set; get; set;
} }
@ -75,14 +76,11 @@ namespace LeanCloud.Realtime {
get; set; get; set;
} }
internal LCIMMessage() { public bool Mentioned {
get; internal set;
} }
internal virtual void Decode(DirectCommand direct) { internal LCIMMessage() {
ConversationId = direct.Cid;
Id = direct.Id;
FromClientId = direct.FromPeerId;
SentTimestamp = direct.Timestamp;
} }
} }
} }

View File

@ -1,8 +1,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using Newtonsoft.Json; using Newtonsoft.Json;
using LeanCloud.Realtime.Protocol;
using LeanCloud.Storage.Internal;
using LeanCloud.Storage.Internal.Codec; using LeanCloud.Storage.Internal.Codec;
using LeanCloud.Storage.Internal;
namespace LeanCloud.Realtime { namespace LeanCloud.Realtime {
public abstract class LCIMTypedMessage : LCIMMessage { public abstract class LCIMTypedMessage : LCIMMessage {
@ -40,12 +39,6 @@ namespace LeanCloud.Realtime {
return msgData; return msgData;
} }
internal override void Decode(DirectCommand direct) {
base.Decode(direct);
Dictionary<string, object> msgData = JsonConvert.DeserializeObject<Dictionary<string, object>>(direct.Msg, new LCJsonConverter());
DecodeMessageData(msgData);
}
protected virtual void DecodeMessageData(Dictionary<string, object> msgData) { protected virtual void DecodeMessageData(Dictionary<string, object> msgData) {
MessageType = (int)msgData["_lctype"]; MessageType = (int)msgData["_lctype"];
if (msgData.TryGetValue("_lcattrs", out object attrObj)) { if (msgData.TryGetValue("_lcattrs", out object attrObj)) {
@ -53,9 +46,11 @@ namespace LeanCloud.Realtime {
} }
} }
internal static LCIMTypedMessage Deserialize(Dictionary<string, object> messageData) { internal static LCIMTypedMessage Deserialize(string json) {
Dictionary<string, object> msgData = JsonConvert.DeserializeObject<Dictionary<string, object>>(json,
new LCJsonConverter());
LCIMTypedMessage message = null; LCIMTypedMessage message = null;
int msgType = (int)messageData["_lctype"]; int msgType = (int)msgData["_lctype"];
switch (msgType) { switch (msgType) {
case -1: case -1:
message = new LCIMTextMessage(); message = new LCIMTextMessage();
@ -76,9 +71,11 @@ namespace LeanCloud.Realtime {
message = new LCIMFileMessage(); message = new LCIMFileMessage();
break; break;
default: default:
// TODO 用户自定义类型消息
break; break;
} }
//message.Decode(direct); message.DecodeMessageData(msgData);
return message; return message;
} }
} }

View File

@ -111,10 +111,11 @@ namespace Realtime.Test {
string otherId = Guid.NewGuid().ToString(); string otherId = Guid.NewGuid().ToString();
LCIMConversation conversation = await client.CreateConversation(new List<string> { otherId }); LCIMConversation conversation = await client.CreateConversation(new List<string> { otherId });
conversation.Name = "leancloud"; await conversation.UpdateInfo(new Dictionary<string, object> {
conversation["k1"] = "v1"; { "name", "leancloud" },
conversation["k2"] = "v2"; { "k1", "v1" },
await conversation.UpdateInfo(); { "k2", "v2" }
});
Assert.AreEqual(conversation.Name, "leancloud"); Assert.AreEqual(conversation.Name, "leancloud");
Assert.AreEqual(conversation["k1"], "v1"); Assert.AreEqual(conversation["k1"], "v1");