diff --git a/Realtime/Conversation/LCIMConversation.cs b/Realtime/Conversation/LCIMConversation.cs index 4dc9867..d34fce3 100644 --- a/Realtime/Conversation/LCIMConversation.cs +++ b/Realtime/Conversation/LCIMConversation.cs @@ -72,7 +72,19 @@ namespace LeanCloud.Realtime { } public async Task Send(LCIMMessage message) { - return null; + DirectCommand direct = new DirectCommand { + FromPeerId = client.ClientId, + Cid = Id, + Msg = message.Serialize(), + }; + GenericCommand command = client.NewDirectCommand(); + command.DirectMessage = direct; + GenericCommand response = await client.client.SendRequest(command); + // 消息发送应答 + AckCommand ack = response.AckMessage; + message.Id = ack.Uid; + message.DeliveredTimestamp = ack.T; + return message; } public async Task Recall(LCIMMessage message) { diff --git a/Realtime/LCIMClient.cs b/Realtime/LCIMClient.cs index 3cadfa6..92caeb0 100644 --- a/Realtime/LCIMClient.cs +++ b/Realtime/LCIMClient.cs @@ -9,12 +9,14 @@ using Newtonsoft.Json; namespace LeanCloud.Realtime { public class LCIMClient { - private string clientId; - - private LCWebSocketClient client; + internal LCWebSocketClient client; private Dictionary conversationDict; + public string ClientId { + get; private set; + } + /// /// 当前用户被加入某个对话的黑名单 /// @@ -69,7 +71,7 @@ namespace LeanCloud.Realtime { } public LCIMClient(string clientId) { - this.clientId = clientId; + ClientId = clientId; conversationDict = new Dictionary(); } @@ -135,7 +137,7 @@ namespace LeanCloud.Realtime { } command.ConvMessage = conv; GenericCommand response = await client.SendRequest(command); - LCIMConversation conversation = new LCIMConversation(this); + LCIMConversation conversation = GetOrCreateConversation(response.ConvMessage.Cid); conversation.MergeFrom(response.ConvMessage); conversationDict[conversation.Id] = conversation; return conversation; @@ -177,25 +179,39 @@ namespace LeanCloud.Realtime { } private void OnConversationJoined(ConvCommand conv) { - if (conversationDict.TryGetValue(conv.Cid, out LCIMConversation conversation)) { - conversation.MergeFrom(conv); - } + LCIMConversation conversation = GetOrCreateConversation(conv.Cid); + conversation.MergeFrom(conv); OnInvited?.Invoke(conversation, conv.InitBy); } private void OnConversationMembersJoined(ConvCommand conv) { - if (conversationDict.TryGetValue(conv.Cid, out LCIMConversation conversation)) { - conversation.MergeFrom(conv); - } + LCIMConversation conversation = GetOrCreateConversation(conv.Cid); + conversation.MergeFrom(conv); OnMembersJoined?.Invoke(conversation, conv.M.ToList(), conv.InitBy); } - private GenericCommand NewCommand(CommandType cmd, OpType op) { + private LCIMConversation GetOrCreateConversation(string convId) { + if (!conversationDict.TryGetValue(convId, out LCIMConversation conversation)) { + conversation = new LCIMConversation(this); + conversationDict.Add(convId, conversation); + } + return conversation; + } + + internal GenericCommand NewCommand(CommandType cmd, OpType op) { return new GenericCommand { Cmd = cmd, Op = op, AppId = LCApplication.AppId, - PeerId = clientId, + PeerId = ClientId, + }; + } + + internal GenericCommand NewDirectCommand() { + return new GenericCommand { + Cmd = CommandType.Direct, + AppId = LCApplication.AppId, + PeerId = ClientId, }; } } diff --git a/Realtime/Message/LCIMBinaryMessage.cs b/Realtime/Message/LCIMBinaryMessage.cs new file mode 100644 index 0000000..aef85de --- /dev/null +++ b/Realtime/Message/LCIMBinaryMessage.cs @@ -0,0 +1,15 @@ +using System; + +namespace LeanCloud.Realtime { + public class LCIMBinaryMessage : LCIMMessage { + private byte[] data; + + public LCIMBinaryMessage(byte[] data) { + this.data = data; + } + + internal override string Serialize() { + throw new NotImplementedException(); + } + } +} diff --git a/Realtime/Message/LCIMMessage.cs b/Realtime/Message/LCIMMessage.cs index 2854bd8..c9cf132 100644 --- a/Realtime/Message/LCIMMessage.cs +++ b/Realtime/Message/LCIMMessage.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; namespace LeanCloud.Realtime { - public class LCIMMessage { + public abstract class LCIMMessage { public string ConversationId { get; set; } @@ -15,36 +15,48 @@ namespace LeanCloud.Realtime { get; set; } - public int SentTimestamp { - get; set; + public long SentTimestamp { + get; internal set; } public DateTime SentAt { - get; set; + get { + return DateTimeOffset.FromUnixTimeMilliseconds(SentTimestamp) + .LocalDateTime; + } } - public int DeliveredTimestamp { - get; set; + public long DeliveredTimestamp { + get; internal set; } public DateTime DeliveredAt { - get; set; + get { + return DateTimeOffset.FromUnixTimeMilliseconds(DeliveredTimestamp) + .LocalDateTime; + } } - public int ReadTimestamp { - get; set; + public long ReadTimestamp { + get; internal set; } public DateTime ReadAt { - get; set; + get { + return DateTimeOffset.FromUnixTimeMilliseconds(ReadTimestamp) + .LocalDateTime; + } } - public int PatchedTimestamp { - get; set; + public long PatchedTimestamp { + get; internal set; } public DateTime PatchedAt { - get; set; + get { + return DateTimeOffset.FromUnixTimeMilliseconds(PatchedTimestamp) + .LocalDateTime; + } } public List MentionList { @@ -55,6 +67,6 @@ namespace LeanCloud.Realtime { } - + internal abstract string Serialize(); } } diff --git a/Realtime/Message/LCIMTextMessage.cs b/Realtime/Message/LCIMTextMessage.cs index 1ee027b..2f45c51 100644 --- a/Realtime/Message/LCIMTextMessage.cs +++ b/Realtime/Message/LCIMTextMessage.cs @@ -1,8 +1,18 @@ using System; +using Newtonsoft.Json; namespace LeanCloud.Realtime { - public class LCIMTextMessage { - public LCIMTextMessage() { + public class LCIMTextMessage : LCIMTypedMessage { + const int TextMessageType = -1; + + private string text; + + public LCIMTextMessage(string text) : base(TextMessageType) { + this.text = text; + } + + internal override string Serialize() { + return text; } } } diff --git a/Realtime/Message/LCIMTypedMessage.cs b/Realtime/Message/LCIMTypedMessage.cs index 75e864f..680977b 100644 --- a/Realtime/Message/LCIMTypedMessage.cs +++ b/Realtime/Message/LCIMTypedMessage.cs @@ -1,7 +1,15 @@ using System; -namespace LeanCloud.Realtime.Message { - public class LCIMTypedMessage { - public LCIMTypedMessage() { + +namespace LeanCloud.Realtime { + public class LCIMTypedMessage : LCIMMessage { + protected int type; + + protected LCIMTypedMessage(int type) { + this.type = type; + } + + internal override string Serialize() { + throw new NotImplementedException(); } } } diff --git a/Test/Realtime.Test/Message.cs b/Test/Realtime.Test/Message.cs new file mode 100644 index 0000000..e27dc54 --- /dev/null +++ b/Test/Realtime.Test/Message.cs @@ -0,0 +1,42 @@ +using NUnit.Framework; +using System; +using System.Threading.Tasks; +using System.Collections.Generic; +using LeanCloud; +using LeanCloud.Common; +using LeanCloud.Realtime; + +namespace Realtime.Test { + public class Message { + [SetUp] + public void SetUp() { + LCLogger.LogDelegate += Utils.Print; + LCApplication.Initialize("ikGGdRE2YcVOemAaRbgp1xGJ-gzGzoHsz", "NUKmuRbdAhg1vrb2wexYo1jo", "https://ikggdre2.lc-cn-n1-shared.com"); + } + + [TearDown] + public void TearDown() { + LCLogger.LogDelegate -= Utils.Print; + } + + [Test] + public async Task Send() { + try { + string clientId = Guid.NewGuid().ToString(); + LCIMClient client = new LCIMClient(clientId); + await client.Open(); + List memberIdList = new List { "world" }; + string name = Guid.NewGuid().ToString(); + LCIMConversation conversation = await client.CreateConversation(memberIdList, name: name, unique: false); + LCIMTextMessage textMessage = new LCIMTextMessage("hello, world"); + await conversation.Send(textMessage); + + TestContext.WriteLine(textMessage.Id); + TestContext.WriteLine(textMessage.DeliveredAt); + Assert.NotNull(textMessage.Id); + } catch (Exception e) { + LCLogger.Error(e.Message); + } + } + } +} diff --git a/Test/RealtimeConsole/Program.cs b/Test/RealtimeConsole/Program.cs index ac7d8ae..3e7400a 100644 --- a/Test/RealtimeConsole/Program.cs +++ b/Test/RealtimeConsole/Program.cs @@ -54,9 +54,10 @@ namespace RealtimeConsole { List memberIdList = new List { "world", "code" }; string name = Guid.NewGuid().ToString(); - _ = await client.CreateTemporaryConversation(memberIdList); - //_ = await client.CreateChatRoom(name); - //_ = await client.CreateConversation(memberIdList, name: name, unique: false); + LCIMConversation conversation = await client.CreateConversation(memberIdList, name: name, unique: false); + + LCIMTextMessage textMessage = new LCIMTextMessage("hello, world"); + await conversation.Send(textMessage); } } }