* LCIMClient.cs:
* LCConnection.cs: * LCWebSocketClient.cs: * Program.cs: chore
parent
aeb063f6f8
commit
b89709b21d
|
@ -9,6 +9,9 @@ using LeanCloud.Common;
|
|||
using LeanCloud.Storage;
|
||||
|
||||
namespace LeanCloud.Realtime.Internal.Connection {
|
||||
/// <summary>
|
||||
/// 连接层,只与数据协议相关
|
||||
/// </summary>
|
||||
internal class LCConnection {
|
||||
private const int SEND_TIMEOUT = 10000;
|
||||
|
||||
|
|
|
@ -5,6 +5,9 @@ using LeanCloud.Common;
|
|||
using LeanCloud.Realtime.Internal.Router;
|
||||
|
||||
namespace LeanCloud.Realtime.Internal.WebSocket {
|
||||
/// <summary>
|
||||
/// WebSocket 客户端,只与通信协议相关
|
||||
/// </summary>
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,9 @@ using LeanCloud.Realtime.Internal.Controller;
|
|||
using LeanCloud.Realtime.Internal.Connection;
|
||||
|
||||
namespace LeanCloud.Realtime {
|
||||
/// <summary>
|
||||
/// 通信客户端
|
||||
/// </summary>
|
||||
public class LCIMClient {
|
||||
internal Dictionary<string, LCIMConversation> ConversationDict;
|
||||
|
||||
|
@ -185,6 +188,20 @@ namespace LeanCloud.Realtime {
|
|||
get; set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 消息已送达
|
||||
/// </summary>
|
||||
public Action<LCIMConversation, string> OnMessageDelivered {
|
||||
get; set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 消息已读
|
||||
/// </summary>
|
||||
public Action<LCIMConversation, string> OnMessageRead {
|
||||
get; set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 未读消息数目更新
|
||||
/// </summary>
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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<int, int> d = new Dictionary<int, int>();
|
||||
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();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue