diff --git a/Realtime/Internal/Connection/LCConnection.cs b/Realtime/Internal/Connection/LCConnection.cs
index 6b89760..6311b42 100644
--- a/Realtime/Internal/Connection/LCConnection.cs
+++ b/Realtime/Internal/Connection/LCConnection.cs
@@ -9,6 +9,9 @@ using LeanCloud.Common;
using LeanCloud.Storage;
namespace LeanCloud.Realtime.Internal.Connection {
+ ///
+ /// 连接层,只与数据协议相关
+ ///
internal class LCConnection {
private const int SEND_TIMEOUT = 10000;
diff --git a/Realtime/Internal/WebSocket/LCWebSocketClient.cs b/Realtime/Internal/WebSocket/LCWebSocketClient.cs
index a055669..c8f2055 100644
--- a/Realtime/Internal/WebSocket/LCWebSocketClient.cs
+++ b/Realtime/Internal/WebSocket/LCWebSocketClient.cs
@@ -5,6 +5,9 @@ using LeanCloud.Common;
using LeanCloud.Realtime.Internal.Router;
namespace LeanCloud.Realtime.Internal.WebSocket {
+ ///
+ /// WebSocket 客户端,只与通信协议相关
+ ///
internal class LCWebSocketClient {
// .net standard 2.0 好像在拼合 Frame 时有 bug,所以将这个值调整大一些
private const int RECV_BUFFER_SIZE = 1024 * 5;
@@ -28,11 +31,11 @@ namespace LeanCloud.Realtime.Internal.WebSocket {
internal async Task Connect() {
LCRTMServer rtmServer = await router.GetServer();
try {
- LCLogger.Debug($"Connect Primary Server");
+ LCLogger.Debug($"Primary Server");
await Connect(rtmServer.Primary);
} catch (Exception e) {
LCLogger.Error(e.Message);
- LCLogger.Debug($"Connect Secondary");
+ LCLogger.Debug($"Secondary Server");
await Connect(rtmServer.Secondary);
}
@@ -41,7 +44,7 @@ namespace LeanCloud.Realtime.Internal.WebSocket {
}
private async Task Connect(string server) {
- LCLogger.Debug($"Connect WebSocket: {server}");
+ LCLogger.Debug($"Connecting WebSocket: {server}");
Task timeoutTask = Task.Delay(5000);
ws = new ClientWebSocket();
ws.Options.AddSubProtocol("lc.protobuf2.3");
@@ -54,6 +57,7 @@ namespace LeanCloud.Realtime.Internal.WebSocket {
}
internal async Task Close() {
+ LCLogger.Debug("Closing WebSocket");
OnMessage = null;
OnDisconnect = null;
OnReconnect = null;
@@ -68,7 +72,7 @@ namespace LeanCloud.Realtime.Internal.WebSocket {
} finally {
ws.Abort();
ws.Dispose();
- LCLogger.Debug("Closed WebSocket.");
+ LCLogger.Debug("Closed WebSocket");
}
}
@@ -82,7 +86,9 @@ namespace LeanCloud.Realtime.Internal.WebSocket {
throw e;
}
} else {
- throw new Exception($"Error Websocket state: {ws.State}");
+ string message = $"Error Websocket state: {ws.State}";
+ LCLogger.Error(message);
+ throw new Exception(message);
}
}
diff --git a/Realtime/LCIMClient.cs b/Realtime/LCIMClient.cs
index 8e0919b..177b3ca 100644
--- a/Realtime/LCIMClient.cs
+++ b/Realtime/LCIMClient.cs
@@ -9,6 +9,9 @@ using LeanCloud.Realtime.Internal.Controller;
using LeanCloud.Realtime.Internal.Connection;
namespace LeanCloud.Realtime {
+ ///
+ /// 通信客户端
+ ///
public class LCIMClient {
internal Dictionary ConversationDict;
@@ -185,6 +188,20 @@ namespace LeanCloud.Realtime {
get; set;
}
+ ///
+ /// 消息已送达
+ ///
+ public Action OnMessageDelivered {
+ get; set;
+ }
+
+ ///
+ /// 消息已读
+ ///
+ public Action OnMessageRead {
+ get; set;
+ }
+
///
/// 未读消息数目更新
///
@@ -233,6 +250,10 @@ namespace LeanCloud.Realtime {
get; private set;
}
+ internal LCIMRcpController RcpController {
+ get; private set;
+ }
+
#region 接口
public LCIMClient(string clientId,
@@ -246,6 +267,7 @@ namespace LeanCloud.Realtime {
MessageController = new LCIMMessageController(this);
UnreadController = new LCIMUnreadController(this);
GoAwayController = new LCIMGoAwayController(this);
+ RcpController = new LCIMRcpController(this);
Connection = new LCConnection(Id) {
OnNotification = OnConnectionNotification,
@@ -410,6 +432,9 @@ namespace LeanCloud.Realtime {
case CommandType.Goaway:
_ = GoAwayController.OnNotification(notification);
break;
+ case CommandType.Rcp:
+ _ = RcpController.OnNotification(notification);
+ break;
default:
break;
}
diff --git a/Test/RealtimeConsole/Program.cs b/Test/RealtimeConsole/Program.cs
index 4a9ddd0..c884c43 100644
--- a/Test/RealtimeConsole/Program.cs
+++ b/Test/RealtimeConsole/Program.cs
@@ -14,14 +14,23 @@ namespace RealtimeConsole {
LCLogger.LogDelegate += (level, info) => {
switch (level) {
- case LCLogLevel.Debug:
- Console.WriteLine($"[DEBUG]\n{info}");
+ case LCLogLevel.Debug: {
+ Console.ForegroundColor = ConsoleColor.Green;
+ Console.WriteLine($"{DateTime.Now} [DEBUG]\n{info}");
+ Console.ResetColor();
+ }
break;
- case LCLogLevel.Warn:
- Console.WriteLine($"[WARNING]\n{info}");
+ case LCLogLevel.Warn: {
+ Console.ForegroundColor = ConsoleColor.Yellow;
+ Console.WriteLine($"{DateTime.Now} [WARNING]\n{info}");
+ Console.ResetColor();
+ }
break;
- case LCLogLevel.Error:
- Console.WriteLine($"[ERROR]\n{info}");
+ case LCLogLevel.Error: {
+ Console.ForegroundColor = ConsoleColor.Red;
+ Console.WriteLine($"{DateTime.Now} [ERROR]\n{info}");
+ Console.ResetColor();
+ }
break;
default:
Console.WriteLine(info);
@@ -32,14 +41,22 @@ namespace RealtimeConsole {
SingleThreadSynchronizationContext.Run(async () => {
Console.WriteLine($"start at {Thread.CurrentThread.ManagedThreadId}");
- await Run("cc4");
+ //await Run("cc1");
//await ChatRoom();
//await TemporaryConversation();
//await CreateConversation();
//await QueryMyConversation();
+ //await AutoSendMessage();
+
+ //await KeepAlive();
+
+ await OpenAndClose();
+
Console.WriteLine($"done at {Thread.CurrentThread.ManagedThreadId}");
});
+ //AutoSendMessage().Wait();
+
//Conversation().Wait();
//_ = Signature();
@@ -65,6 +82,24 @@ namespace RealtimeConsole {
Console.ReadKey(true);
}
+ static async Task KeepAlive() {
+ LCIMClient client = new LCIMClient("cc1");
+ await client.Open();
+ }
+
+ static async Task AutoSendMessage() {
+ LCIMClient client = new LCIMClient("cc1");
+ await client.Open();
+ LCIMConversation conversation = await client.CreateConversation(new string[] { "cc2", "cc3", "cc5" });
+ int count = 0;
+ while (count < 10) {
+ LCIMTextMessage textMessage = new LCIMTextMessage($"hello, {count}");
+ await conversation.Send(textMessage);
+ await Task.Delay(5000);
+ count++;
+ }
+ }
+
static async Task DemoAsync() {
Dictionary d = new Dictionary();
for (int i = 0; i < 10000; i++) {
@@ -86,17 +121,16 @@ namespace RealtimeConsole {
Console.WriteLine($"unread: {conv.Id}");
}
};
- client.OnMessage = (conversation, message) => {
+ client.OnMessage = async (conversation, message) => {
Console.WriteLine($"recv: {conversation.Id}, {message.Id} at {Thread.CurrentThread.ManagedThreadId}");
+ await conversation.Read();
};
}
static async Task CreateConversation() {
LCIMClient cc1 = new LCIMClient("cc1");
await cc1.Open();
- //await cc1.CreateChatRoom("leancloud chat");
- await cc1.CreateTemporaryConversation(new string[] { "cc2", "cc3" });
- //await cc1.CreateConversation(new string[] { "cc4" });
+ await cc1.CreateConversation(new string[] { "cc2", "cc3", "cc5" });
}
static async Task QueryMyConversation() {
@@ -146,6 +180,7 @@ namespace RealtimeConsole {
static async Task OpenAndClose() {
LCIMClient o1 = new LCIMClient("o1");
await o1.Open();
+ await Task.Delay(30000);
await o1.Close();
}