diff --git a/AuroraNative/API/Api.cs b/AuroraNative/API/Api.cs
index 6f57e84..db79fd6 100644
--- a/AuroraNative/API/Api.cs
+++ b/AuroraNative/API/Api.cs
@@ -1,7 +1,9 @@
using AuroraNative.EventArgs;
using AuroraNative.WebSockets;
+using Microsoft.Extensions.Caching.Memory;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
+using System;
using System.Threading;
using System.Threading.Tasks;
@@ -10,7 +12,7 @@ namespace AuroraNative
///
/// API 类
///
- public class Api
+ public sealed class Api
{
#region --变量--
@@ -18,18 +20,28 @@ namespace AuroraNative
/// 任务队列
///
internal static JObject TaskList = new JObject();
+ internal static MemoryCache Cache = new MemoryCache(new MemoryCacheOptions());
private readonly BaseWebSocket WebSocket;
#endregion
+ #region --属性--
+
+ ///
+ /// 获取API实例
+ ///
+ public static Api CurrentApi => (Api)Cache.Get($"API{AppDomain.CurrentDomain.Id}");
+
+ #endregion
+
#region --构造函数--
///
/// 构建函数
///
/// WebSocket句柄
- public Api(BaseWebSocket WebSocket)
+ private Api(BaseWebSocket WebSocket)
{
this.WebSocket = WebSocket;
}
@@ -856,7 +868,8 @@ namespace AuroraNative
return null;
}
- private static JObject GetFeedback(string UniqueCode) {
+ private static JObject GetFeedback(string UniqueCode)
+ {
JObject FBJson = new JObject();
do
@@ -868,9 +881,22 @@ namespace AuroraNative
break;
}
Thread.Sleep(10);
- }while (FBJson["status"] == null);
+ } while (FBJson["status"] == null);
return FBJson;
}
+
+ internal static Api Create(BaseWebSocket WebSocket)
+ {
+ Api api = new Api(WebSocket);
+ Cache.Set($"API{AppDomain.CurrentDomain.Id}", api);
+ return api;
+ }
+
+ internal static void Destroy()
+ {
+ Cache.Remove($"API{AppDomain.CurrentDomain.Id}");
+ }
+
#endregion
}
}
diff --git a/AuroraNative/AuroraNative.csproj b/AuroraNative/AuroraNative.csproj
index 20db5b0..e84de38 100644
--- a/AuroraNative/AuroraNative.csproj
+++ b/AuroraNative/AuroraNative.csproj
@@ -15,13 +15,13 @@
false
false
true
- 0.1.0.0311
- 0.1.0.0311
+ 0.2.0.0312
+ 0.2.0.0312
Icon.png
false
AuroraNative
AuroraNative
- 0.1.0-alpha
+ 0.2.0-alpha
true
@@ -41,6 +41,7 @@
+
diff --git a/AuroraNative/AuroraNative.xml b/AuroraNative/AuroraNative.xml
index 7163e89..5f3e9ad 100644
--- a/AuroraNative/AuroraNative.xml
+++ b/AuroraNative/AuroraNative.xml
@@ -14,6 +14,11 @@
任务队列
+
+
+ 获取API实例
+
+
构建函数
@@ -1784,6 +1789,69 @@
异常 类 -- 关于WebSocket异常
+
+
+ 彩色日志输出类
+
+
+
+
+ 日志级别设定默认 Info
+
+
+
+
+ 输出一个等级为 调试 的信息
+
+ 要输出的信息
+ 输出的方法名,可选传入
+
+
+
+ 输出一个等级为 信息 的信息
+
+ 要输出的信息
+ 输出的方法名,可选传入
+
+
+
+ 输出一个等级为 警告 的信息
+
+ 要输出的信息
+ 输出的方法名,可选传入
+
+
+
+ 输出一个等级为 错误 的信息
+
+ 要输出的信息
+ 输出的方法名,可选传入
+
+
+
+ 表示日志信息等级的枚举
+
+
+
+
+ 表示输出日志的等级是 "调试" 级别
+
+
+
+
+ 表示输出日志的等级是 "信息" 级别
+
+
+
+
+ 表示输出日志的等级是 "警告" 级别
+
+
+
+
+ 表示输出日志的等级是 "错误" 级别
+
+
通用方法 类
@@ -1815,16 +1883,6 @@
WebSocket 基础类
-
-
- Websocket句柄
-
-
-
-
- 事件钩子
-
-
发送数据到服务端/客户端
@@ -1842,6 +1900,12 @@
WebSocket服务端地址请记得带端口号
+
+
+ 创建一个 实例
+
+ 重写后的事件类实例
+
创建并连接到WebSocket服务器
@@ -1863,6 +1927,12 @@
WebSocket监听端口
+
+
+ 创建一个 实例
+
+ 重写后的事件类实例
+
创建WebSocket服务器并监听端口
diff --git a/AuroraNative/Event.cs b/AuroraNative/Event.cs
index 186fe40..f016728 100644
--- a/AuroraNative/Event.cs
+++ b/AuroraNative/Event.cs
@@ -1,4 +1,5 @@
using AuroraNative.EventArgs;
+using AuroraNative.WebSockets;
using Newtonsoft.Json.Linq;
namespace AuroraNative
diff --git a/AuroraNative/Logger.cs b/AuroraNative/Logger.cs
new file mode 100644
index 0000000..04f7902
--- /dev/null
+++ b/AuroraNative/Logger.cs
@@ -0,0 +1,110 @@
+using System;
+
+namespace AuroraNative
+{
+ ///
+ /// 彩色日志输出类
+ ///
+ public static class Logger
+ {
+ #region --属性--
+
+ ///
+ /// 日志级别设定默认 Info
+ ///
+ public static LogLevel LogLevel = LogLevel.Info;
+
+ #endregion
+
+ #region --公开函数--
+
+ ///
+ /// 输出一个等级为 调试 的信息
+ ///
+ /// 要输出的信息
+ /// 输出的方法名,可选传入
+ public static void Debug(string Message, string MethodName = null) {
+ if (LogLevel <= LogLevel.Debug) {
+ Output(Message, ConsoleColor.Gray, LogLevel.Debug, MethodName);
+ }
+ }
+
+ ///
+ /// 输出一个等级为 信息 的信息
+ ///
+ /// 要输出的信息
+ /// 输出的方法名,可选传入
+ public static void Info(string Message, string MethodName = null)
+ {
+ if (LogLevel <= LogLevel.Info)
+ {
+ Output(Message, ConsoleColor.White, LogLevel.Info, MethodName);
+ }
+ }
+
+ ///
+ /// 输出一个等级为 警告 的信息
+ ///
+ /// 要输出的信息
+ /// 输出的方法名,可选传入
+ public static void Warning(string Message, string MethodName = null)
+ {
+ if (LogLevel <= LogLevel.Warning)
+ {
+ Output(Message, ConsoleColor.Yellow, LogLevel.Warning, MethodName);
+ }
+ }
+
+ ///
+ /// 输出一个等级为 错误 的信息
+ ///
+ /// 要输出的信息
+ /// 输出的方法名,可选传入
+ public static void Error(string Message, string MethodName = null)
+ {
+ if (LogLevel <= LogLevel.Error)
+ {
+ Output(Message, ConsoleColor.Red, LogLevel.Error, MethodName);
+ }
+ }
+
+ #endregion
+
+ #region --私有函数--
+
+ internal static void Output(string Message, ConsoleColor Color,LogLevel Level, string MethodName) {
+ Console.ForegroundColor = Color;
+ if (MethodName != null) {
+ Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss fff") + $" [{Level}]" + $" [{MethodName}] " + Message);
+ }
+ else {
+ Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss") + $" [{Level}] " + Message);
+ }
+ Console.ForegroundColor = ConsoleColor.White;
+ }
+
+ #endregion
+ }
+
+ ///
+ /// 表示日志信息等级的枚举
+ ///
+ public enum LogLevel {
+ ///
+ /// 表示输出日志的等级是 "调试" 级别
+ ///
+ Debug = 0,
+ ///
+ /// 表示输出日志的等级是 "信息" 级别
+ ///
+ Info = 1,
+ ///
+ /// 表示输出日志的等级是 "警告" 级别
+ ///
+ Warning = 2,
+ ///
+ /// 表示输出日志的等级是 "错误" 级别
+ ///
+ Error = 3
+ }
+}
diff --git a/AuroraNative/WebSockets/BaseWebSocket.cs b/AuroraNative/WebSockets/BaseWebSocket.cs
index 4c14c56..9fa23c7 100644
--- a/AuroraNative/WebSockets/BaseWebSocket.cs
+++ b/AuroraNative/WebSockets/BaseWebSocket.cs
@@ -17,15 +17,8 @@ namespace AuroraNative.WebSockets
{
#region --变量--
- ///
- /// Websocket句柄
- ///
internal WebSocket WebSocket;
- ///
- /// 事件钩子
- ///
- public Event EventHook;
-
+ internal Event EventHook;
internal JObject Json;
internal static Type[] AttributeTypes;
diff --git a/AuroraNative/WebSockets/Client.cs b/AuroraNative/WebSockets/Client.cs
index e7f1250..6517a21 100644
--- a/AuroraNative/WebSockets/Client.cs
+++ b/AuroraNative/WebSockets/Client.cs
@@ -34,6 +34,12 @@ namespace AuroraNative.WebSockets
AttributeTypes = Assembly.GetExecutingAssembly().GetTypes().Where(p => p.IsAbstract == false && p.IsInterface == false && typeof(Attribute).IsAssignableFrom(p)).ToArray();
}
+ ///
+ /// 创建一个 实例
+ ///
+ /// 重写后的事件类实例
+ public Client(Event Event) => EventHook = Event;
+
#endregion
#region --公开函数--
@@ -43,16 +49,32 @@ namespace AuroraNative.WebSockets
///
public bool Create()
{
- WebSocket = new ClientWebSocket();
- if (WebSocket is ClientWebSocket socket) {
- Task Connect = socket.ConnectAsync(new Uri("ws://" + Host + "/"), CancellationToken.None);
- Connect.Wait();
- if (WebSocket.State == WebSocketState.Open)
+ Logger.Debug("正向WebSocket已创建,准备连接...", $"{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}");
+ for (int i = 1;i < 4;i++) {
+ try
{
- Task.Run(Feedback);
- return true;
+ WebSocket = new ClientWebSocket();
+ if (WebSocket is ClientWebSocket socket)
+ {
+ Logger.Debug($"准备连接至IP:{Host}", $"{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}");
+ Task Connect = socket.ConnectAsync(new Uri("ws://" + Host + "/"), CancellationToken.None);
+ Connect.Wait();
+ if (WebSocket.State == WebSocketState.Open)
+ {
+ Logger.Info("已连接至 go-cqhttp 服务器!");
+ Task.Run(Feedback);
+ Api.Create(this);
+ return true;
+ }
+ }
+ }
+ catch (AggregateException)
+ {
+ Logger.Warning($"连接到 go-cqhttp 服务器失败!五秒后重试(重试次数:{i})...", $"{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}");
+ Thread.Sleep(5000);
}
}
+ Logger.Error("连接到 go-cqhttp 服务器失败!请检查IP是否正确(需要携带端口号)或确认服务器是否启动和初始化完毕!", $"{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}");
return false;
}
@@ -61,8 +83,17 @@ namespace AuroraNative.WebSockets
///
public void Dispose()
{
- WebSocket.Dispose();
- WebSocket.Abort();
+ Logger.Debug($"准备销毁正向WebSocket...", $"{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}");
+ try
+ {
+ WebSocket.Dispose();
+ WebSocket.Abort();
+ Api.Destroy();
+ Logger.Info("已销毁正向WebSocket");
+ }
+ catch(Exception e) {
+ Logger.Error("销毁正向WebSocket失败!\n" + e.Message, $"{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}");
+ }
}
#endregion
diff --git a/AuroraNative/WebSockets/Server.cs b/AuroraNative/WebSockets/Server.cs
index 87f1f77..3fbb4f2 100644
--- a/AuroraNative/WebSockets/Server.cs
+++ b/AuroraNative/WebSockets/Server.cs
@@ -38,6 +38,12 @@ namespace AuroraNative.WebSockets
AttributeTypes = Assembly.GetExecutingAssembly().GetTypes().Where(p => p.IsAbstract == false && p.IsInterface == false && typeof(Attribute).IsAssignableFrom(p)).ToArray();
}
+ ///
+ /// 创建一个 实例
+ ///
+ /// 重写后的事件类实例
+ public Server(Event Event) => EventHook = Event;
+
#endregion
#region --公开函数--
@@ -47,13 +53,22 @@ namespace AuroraNative.WebSockets
///
public void Create()
{
- Listener = new HttpListener();
- Listener.Prefixes.Add("http://*:" + Port + "/");
- Listener.Start();
- Task.Run(Feedback);
- while (!IsConnect)
+ try
{
- Thread.Sleep(100);
+ Logger.Debug("反向WebSocket已创建,准备监听...", $"{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}");
+ Listener = new HttpListener();
+ Listener.Prefixes.Add("http://*:" + Port + "/");
+ Listener.Start();
+ Logger.Info("开始监听来自 go-cqhttp 客户端的连接...");
+ Task.Run(Feedback);
+ while (!IsConnect) {
+ Thread.Sleep(100);
+ }
+ }
+ catch(HttpListenerException) {
+ Logger.Error("无法启动监听服务器,请确保使用管理员权限运行。否则无法监听!", $"{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}");
+ Console.ReadKey();
+ Environment.Exit(0);
}
}
@@ -62,9 +77,16 @@ namespace AuroraNative.WebSockets
///
public void Dispose()
{
- Listener.Stop();
- WebSocket.Dispose();
- WebSocket.Abort();
+ Logger.Debug($"准备销毁反向WebSocket...", $"{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}");
+ try {
+ Listener.Stop();
+ WebSocket.Dispose();
+ WebSocket.Abort();
+ Api.Destroy();
+ Logger.Info("已销毁反向WebSocket");
+ } catch (Exception e) {
+ Logger.Error("销毁反向WebSocket失败!\n" + e.Message, $"{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}");
+ }
}
#endregion
@@ -78,9 +100,11 @@ namespace AuroraNative.WebSockets
HttpListenerContext Context = await Listener.GetContextAsync();
if (Context.Request.IsWebSocketRequest)
{
+ Logger.Info("收到来自 go-cqhttp 客户端的连接!连接已建立!");
HttpListenerWebSocketContext SocketContext = await Context.AcceptWebSocketAsync(null);
WebSocket = SocketContext.WebSocket;
IsConnect = true;
+ Api.Create(this);
while (WebSocket.State == WebSocketState.Open)
{
await GetEventAsync();
diff --git a/README.md b/README.md
index e148241..35678b2 100644
--- a/README.md
+++ b/README.md
@@ -39,9 +39,15 @@
- 优化内部算法或修改类型(如将返回的JObject类型抽象为新自定义类型) - vX.X.X+1
- 重命名/删除/新增 文件/命名空间/API - vX.X+1.X
+## 文档
+
+开发文档:[点我查看](https://auroranative.mikuy.cn)
+
+> 开发文档是与框架一起更新的,因此文档也处于快速迭代状态。
+
## 兼容性
-### 接口
+### 通讯方式
- [ ] HTTP API
- [ ] 反向 HTTP POST
@@ -50,7 +56,7 @@
## 关于 ISSUE
-如果没有大问题请到 Discussions 处提问
+如果没有大问题请到 [Discussions](https://github.com/timi137137/AuroraNative/discussions) 处提问
以下 ISSUE 会被直接关闭