* LCIMClient.cs:

* LCIMMessage.cs:
* LCIMRecalledMessage.cs:
* LCIMMessageController.cs:
* LCIMSessionController.cs:

* LCIMTypedMessage.cs: chore: 完善消息接口和事件
oneRain 2020-04-26 15:50:06 +08:00
parent 688918a4e7
commit b70e6c7bbb
6 changed files with 62 additions and 12 deletions

View File

@ -56,7 +56,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
// 消息发送应答 // 消息发送应答
AckCommand ack = response.AckMessage; AckCommand ack = response.AckMessage;
message.Id = ack.Uid; message.Id = ack.Uid;
message.DeliveredTimestamp = ack.T; message.SentTimestamp = ack.T;
return message; return message;
} }
@ -72,7 +72,10 @@ namespace LeanCloud.Realtime.Internal.Controller {
PatchItem item = new PatchItem { PatchItem item = new PatchItem {
Cid = convId, Cid = convId,
Mid = message.Id, Mid = message.Id,
Recall = true From = Client.Id,
Recall = true,
Timestamp = message.SentTimestamp,
PatchTimestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
}; };
patch.Patches.Add(item); patch.Patches.Add(item);
GenericCommand request = NewCommand(CommandType.Patch, OpType.Modify); GenericCommand request = NewCommand(CommandType.Patch, OpType.Modify);
@ -94,8 +97,10 @@ namespace LeanCloud.Realtime.Internal.Controller {
PatchItem item = new PatchItem { PatchItem item = new PatchItem {
Cid = convId, Cid = convId,
Mid = oldMessage.Id, Mid = oldMessage.Id,
Timestamp = oldMessage.DeliveredTimestamp, From = Client.Id,
Recall = false, Recall = false,
Timestamp = oldMessage.SentTimestamp,
PatchTimestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
}; };
if (newMessage is LCIMTypedMessage typedMessage) { if (newMessage is LCIMTypedMessage typedMessage) {
item.Data = JsonConvert.SerializeObject(typedMessage.Encode()); item.Data = JsonConvert.SerializeObject(typedMessage.Encode());
@ -218,6 +223,41 @@ namespace LeanCloud.Realtime.Internal.Controller {
#region 消息处理 #region 消息处理
internal override async Task OnNotification(GenericCommand notification) { 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; DirectCommand direct = notification.DirectMessage;
// 反序列化消息 // 反序列化消息
LCIMMessage message; LCIMMessage message;

View File

@ -1,7 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using LeanCloud.Storage;
using LeanCloud.Realtime.Protocol; using LeanCloud.Realtime.Protocol;
namespace LeanCloud.Realtime.Internal.Controller { namespace LeanCloud.Realtime.Internal.Controller {
@ -23,6 +22,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
internal async Task Open(bool force) { internal async Task Open(bool force) {
SessionCommand session = await NewSessionCommand(); SessionCommand session = await NewSessionCommand();
session.R = !force; session.R = !force;
session.ConfigBitmap = 0x7B;
GenericCommand request = NewCommand(CommandType.Session, OpType.Open); GenericCommand request = NewCommand(CommandType.Session, OpType.Open);
request.SessionMessage = session; request.SessionMessage = session;
GenericCommand response = await Client.Connection.SendRequest(request); GenericCommand response = await Client.Connection.SendRequest(request);

View File

@ -165,7 +165,7 @@ namespace LeanCloud.Realtime {
/// <summary> /// <summary>
/// 消息被撤回 /// 消息被撤回
/// </summary> /// </summary>
public Action<LCIMConversation, LCIMMessage> OnMessageRecalled { public Action<LCIMConversation, LCIMRecalledMessage> OnMessageRecalled {
get; set; get; set;
} }
@ -449,6 +449,7 @@ namespace LeanCloud.Realtime {
_ = ConversationController.OnNotification(notification); _ = ConversationController.OnNotification(notification);
break; break;
case CommandType.Direct: case CommandType.Direct:
case CommandType.Patch:
_ = MessageController.OnNotification(notification); _ = MessageController.OnNotification(notification);
break; break;
case CommandType.Unread: case CommandType.Unread:

View File

@ -9,6 +9,7 @@ namespace LeanCloud.Realtime {
internal const int VideoMessageType = -4; internal const int VideoMessageType = -4;
internal const int LocationMessageType = -5; internal const int LocationMessageType = -5;
internal const int FileMessageType = -6; internal const int FileMessageType = -6;
internal const int RecalledMessageType = -127;
public string ConversationId { public string ConversationId {
get; set; get; set;

View File

@ -1,7 +1,12 @@
 
namespace LeanCloud.Realtime { namespace LeanCloud.Realtime {
public class LCIMRecalledMessage { /// <summary>
/// 撤回消息
/// </summary>
public class LCIMRecalledMessage : LCIMTypedMessage {
public LCIMRecalledMessage() { public LCIMRecalledMessage() {
} }
internal override int MessageType => RecalledMessageType;
} }
} }

View File

@ -52,24 +52,27 @@ namespace LeanCloud.Realtime {
LCIMTypedMessage message = null; LCIMTypedMessage message = null;
int msgType = (int)msgData["_lctype"]; int msgType = (int)msgData["_lctype"];
switch (msgType) { switch (msgType) {
case -1: case TextMessageType:
message = new LCIMTextMessage(); message = new LCIMTextMessage();
break; break;
case -2: case ImageMessageType:
message = new LCIMImageMessage(); message = new LCIMImageMessage();
break; break;
case -3: case AudioMessageType:
message = new LCIMAudioMessage(); message = new LCIMAudioMessage();
break; break;
case -4: case VideoMessageType:
message = new LCIMVideoMessage(); message = new LCIMVideoMessage();
break; break;
case -5: case LocationMessageType:
message = new LCIMLocationMessage(); message = new LCIMLocationMessage();
break; break;
case -6: case FileMessageType:
message = new LCIMFileMessage(); message = new LCIMFileMessage();
break; break;
case RecalledMessageType:
message = new LCIMRecalledMessage();
break;
default: default:
// TODO 用户自定义类型消息 // TODO 用户自定义类型消息