diff --git a/Realtime/Internal/Controller/LCIMMessageController.cs b/Realtime/Internal/Controller/LCIMMessageController.cs
index 11ec039..830328f 100644
--- a/Realtime/Internal/Controller/LCIMMessageController.cs
+++ b/Realtime/Internal/Controller/LCIMMessageController.cs
@@ -56,7 +56,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
// 消息发送应答
AckCommand ack = response.AckMessage;
message.Id = ack.Uid;
- message.DeliveredTimestamp = ack.T;
+ message.SentTimestamp = ack.T;
return message;
}
@@ -72,7 +72,10 @@ namespace LeanCloud.Realtime.Internal.Controller {
PatchItem item = new PatchItem {
Cid = convId,
Mid = message.Id,
- Recall = true
+ From = Client.Id,
+ Recall = true,
+ Timestamp = message.SentTimestamp,
+ PatchTimestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
};
patch.Patches.Add(item);
GenericCommand request = NewCommand(CommandType.Patch, OpType.Modify);
@@ -94,8 +97,10 @@ namespace LeanCloud.Realtime.Internal.Controller {
PatchItem item = new PatchItem {
Cid = convId,
Mid = oldMessage.Id,
- Timestamp = oldMessage.DeliveredTimestamp,
+ From = Client.Id,
Recall = false,
+ Timestamp = oldMessage.SentTimestamp,
+ PatchTimestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
};
if (newMessage is LCIMTypedMessage typedMessage) {
item.Data = JsonConvert.SerializeObject(typedMessage.Encode());
@@ -218,6 +223,41 @@ namespace LeanCloud.Realtime.Internal.Controller {
#region 消息处理
internal override async Task OnNotification(GenericCommand notification) {
+ if (notification.Cmd == CommandType.Patch) {
+ await OnMessagePatched(notification);
+ } else if (notification.Cmd == CommandType.Direct) {
+ await OnMessaage(notification);
+ }
+ }
+
+ 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);
+ }
+ }
+ }
+
+ private async Task OnMessaage(GenericCommand notification) {
DirectCommand direct = notification.DirectMessage;
// 反序列化消息
LCIMMessage message;
diff --git a/Realtime/Internal/Controller/LCIMSessionController.cs b/Realtime/Internal/Controller/LCIMSessionController.cs
index 6017ca6..f0c5353 100644
--- a/Realtime/Internal/Controller/LCIMSessionController.cs
+++ b/Realtime/Internal/Controller/LCIMSessionController.cs
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
-using LeanCloud.Storage;
using LeanCloud.Realtime.Protocol;
namespace LeanCloud.Realtime.Internal.Controller {
@@ -23,6 +22,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
internal async Task Open(bool force) {
SessionCommand session = await NewSessionCommand();
session.R = !force;
+ session.ConfigBitmap = 0x7B;
GenericCommand request = NewCommand(CommandType.Session, OpType.Open);
request.SessionMessage = session;
GenericCommand response = await Client.Connection.SendRequest(request);
diff --git a/Realtime/LCIMClient.cs b/Realtime/LCIMClient.cs
index 6e87afd..a5e7c24 100644
--- a/Realtime/LCIMClient.cs
+++ b/Realtime/LCIMClient.cs
@@ -165,7 +165,7 @@ namespace LeanCloud.Realtime {
///
/// 消息被撤回
///
- public Action OnMessageRecalled {
+ public Action OnMessageRecalled {
get; set;
}
@@ -449,6 +449,7 @@ namespace LeanCloud.Realtime {
_ = ConversationController.OnNotification(notification);
break;
case CommandType.Direct:
+ case CommandType.Patch:
_ = MessageController.OnNotification(notification);
break;
case CommandType.Unread:
diff --git a/Realtime/Message/LCIMMessage.cs b/Realtime/Message/LCIMMessage.cs
index 786c229..77fc128 100644
--- a/Realtime/Message/LCIMMessage.cs
+++ b/Realtime/Message/LCIMMessage.cs
@@ -9,6 +9,7 @@ namespace LeanCloud.Realtime {
internal const int VideoMessageType = -4;
internal const int LocationMessageType = -5;
internal const int FileMessageType = -6;
+ internal const int RecalledMessageType = -127;
public string ConversationId {
get; set;
diff --git a/Realtime/Message/LCIMRecalledMessage.cs b/Realtime/Message/LCIMRecalledMessage.cs
index a54d243..3706dda 100644
--- a/Realtime/Message/LCIMRecalledMessage.cs
+++ b/Realtime/Message/LCIMRecalledMessage.cs
@@ -1,7 +1,12 @@
namespace LeanCloud.Realtime {
- public class LCIMRecalledMessage {
+ ///
+ /// 撤回消息
+ ///
+ public class LCIMRecalledMessage : LCIMTypedMessage {
public LCIMRecalledMessage() {
}
+
+ internal override int MessageType => RecalledMessageType;
}
}
diff --git a/Realtime/Message/LCIMTypedMessage.cs b/Realtime/Message/LCIMTypedMessage.cs
index fb0a61b..08a5d6d 100644
--- a/Realtime/Message/LCIMTypedMessage.cs
+++ b/Realtime/Message/LCIMTypedMessage.cs
@@ -52,24 +52,27 @@ namespace LeanCloud.Realtime {
LCIMTypedMessage message = null;
int msgType = (int)msgData["_lctype"];
switch (msgType) {
- case -1:
+ case TextMessageType:
message = new LCIMTextMessage();
break;
- case -2:
+ case ImageMessageType:
message = new LCIMImageMessage();
break;
- case -3:
+ case AudioMessageType:
message = new LCIMAudioMessage();
break;
- case -4:
+ case VideoMessageType:
message = new LCIMVideoMessage();
break;
- case -5:
+ case LocationMessageType:
message = new LCIMLocationMessage();
break;
- case -6:
+ case FileMessageType:
message = new LCIMFileMessage();
break;
+ case RecalledMessageType:
+ message = new LCIMRecalledMessage();
+ break;
default:
// TODO 用户自定义类型消息