03/12 Last Update

This commit is contained in:
悠静萝莉
2021-03-12 23:21:30 +08:00
parent 3d032bb22e
commit c6bb234e52
9 changed files with 307 additions and 45 deletions

View File

@@ -1,7 +1,9 @@
using AuroraNative.EventArgs; using AuroraNative.EventArgs;
using AuroraNative.WebSockets; using AuroraNative.WebSockets;
using Microsoft.Extensions.Caching.Memory;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using System;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -10,7 +12,7 @@ namespace AuroraNative
/// <summary> /// <summary>
/// API 类 /// API 类
/// </summary> /// </summary>
public class Api public sealed class Api
{ {
#region ---- #region ----
@@ -18,18 +20,28 @@ namespace AuroraNative
/// 任务队列 /// 任务队列
/// </summary> /// </summary>
internal static JObject TaskList = new JObject(); internal static JObject TaskList = new JObject();
internal static MemoryCache Cache = new MemoryCache(new MemoryCacheOptions());
private readonly BaseWebSocket WebSocket; private readonly BaseWebSocket WebSocket;
#endregion #endregion
#region ----
/// <summary>
/// 获取API实例
/// </summary>
public static Api CurrentApi => (Api)Cache.Get($"API{AppDomain.CurrentDomain.Id}");
#endregion
#region ---- #region ----
/// <summary> /// <summary>
/// 构建函数 /// 构建函数
/// </summary> /// </summary>
/// <param name="WebSocket">WebSocket句柄</param> /// <param name="WebSocket">WebSocket句柄</param>
public Api(BaseWebSocket WebSocket) private Api(BaseWebSocket WebSocket)
{ {
this.WebSocket = WebSocket; this.WebSocket = WebSocket;
} }
@@ -856,7 +868,8 @@ namespace AuroraNative
return null; return null;
} }
private static JObject GetFeedback(string UniqueCode) { private static JObject GetFeedback(string UniqueCode)
{
JObject FBJson = new JObject(); JObject FBJson = new JObject();
do do
@@ -868,9 +881,22 @@ namespace AuroraNative
break; break;
} }
Thread.Sleep(10); Thread.Sleep(10);
}while (FBJson["status"] == null); } while (FBJson["status"] == null);
return FBJson; 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 #endregion
} }
} }

View File

@@ -15,13 +15,13 @@
<SignAssembly>false</SignAssembly> <SignAssembly>false</SignAssembly>
<DelaySign>false</DelaySign> <DelaySign>false</DelaySign>
<EnableNETAnalyzers>true</EnableNETAnalyzers> <EnableNETAnalyzers>true</EnableNETAnalyzers>
<AssemblyVersion>0.1.0.0311</AssemblyVersion> <AssemblyVersion>0.2.0.0312</AssemblyVersion>
<FileVersion>0.1.0.0311</FileVersion> <FileVersion>0.2.0.0312</FileVersion>
<PackageIcon>Icon.png</PackageIcon> <PackageIcon>Icon.png</PackageIcon>
<EnforceCodeStyleInBuild>false</EnforceCodeStyleInBuild> <EnforceCodeStyleInBuild>false</EnforceCodeStyleInBuild>
<AssemblyName>AuroraNative</AssemblyName> <AssemblyName>AuroraNative</AssemblyName>
<RootNamespace>AuroraNative</RootNamespace> <RootNamespace>AuroraNative</RootNamespace>
<Version>0.1.0-alpha</Version> <Version>0.2.0-alpha</Version>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild> <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
</PropertyGroup> </PropertyGroup>
@@ -41,6 +41,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="5.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="12.*" /> <PackageReference Include="Newtonsoft.Json" Version="12.*" />
</ItemGroup> </ItemGroup>

View File

@@ -14,6 +14,11 @@
任务队列 任务队列
</summary> </summary>
</member> </member>
<member name="P:AuroraNative.Api.CurrentApi">
<summary>
获取API实例
</summary>
</member>
<member name="M:AuroraNative.Api.#ctor(AuroraNative.WebSockets.BaseWebSocket)"> <member name="M:AuroraNative.Api.#ctor(AuroraNative.WebSockets.BaseWebSocket)">
<summary> <summary>
构建函数 构建函数
@@ -1784,6 +1789,69 @@
异常 类 -- 关于WebSocket异常 异常 类 -- 关于WebSocket异常
</summary> </summary>
</member> </member>
<member name="T:AuroraNative.Logger">
<summary>
彩色日志输出类
</summary>
</member>
<member name="F:AuroraNative.Logger.LogLevel">
<summary>
日志级别设定<para>默认 Info</para>
</summary>
</member>
<member name="M:AuroraNative.Logger.Debug(System.String,System.String)">
<summary>
输出一个等级为 调试 的信息
</summary>
<param name="Message">要输出的信息</param>
<param name="MethodName">输出的方法名,可选传入</param>
</member>
<member name="M:AuroraNative.Logger.Info(System.String,System.String)">
<summary>
输出一个等级为 信息 的信息
</summary>
<param name="Message">要输出的信息</param>
<param name="MethodName">输出的方法名,可选传入</param>
</member>
<member name="M:AuroraNative.Logger.Warning(System.String,System.String)">
<summary>
输出一个等级为 警告 的信息
</summary>
<param name="Message">要输出的信息</param>
<param name="MethodName">输出的方法名,可选传入</param>
</member>
<member name="M:AuroraNative.Logger.Error(System.String,System.String)">
<summary>
输出一个等级为 错误 的信息
</summary>
<param name="Message">要输出的信息</param>
<param name="MethodName">输出的方法名,可选传入</param>
</member>
<member name="T:AuroraNative.LogLevel">
<summary>
表示日志信息等级的枚举
</summary>
</member>
<member name="F:AuroraNative.LogLevel.Debug">
<summary>
表示输出日志的等级是 "调试" 级别
</summary>
</member>
<member name="F:AuroraNative.LogLevel.Info">
<summary>
表示输出日志的等级是 "信息" 级别
</summary>
</member>
<member name="F:AuroraNative.LogLevel.Warning">
<summary>
表示输出日志的等级是 "警告" 级别
</summary>
</member>
<member name="F:AuroraNative.LogLevel.Error">
<summary>
表示输出日志的等级是 "错误" 级别
</summary>
</member>
<member name="T:AuroraNative.Utils"> <member name="T:AuroraNative.Utils">
<summary> <summary>
通用方法 类 通用方法 类
@@ -1815,16 +1883,6 @@
WebSocket 基础类 WebSocket 基础类
</summary> </summary>
</member> </member>
<member name="F:AuroraNative.WebSockets.BaseWebSocket.WebSocket">
<summary>
Websocket句柄
</summary>
</member>
<member name="F:AuroraNative.WebSockets.BaseWebSocket.EventHook">
<summary>
事件钩子
</summary>
</member>
<member name="M:AuroraNative.WebSockets.BaseWebSocket.Send(AuroraNative.BaseAPI)"> <member name="M:AuroraNative.WebSockets.BaseWebSocket.Send(AuroraNative.BaseAPI)">
<summary> <summary>
发送数据到服务端/客户端 发送数据到服务端/客户端
@@ -1842,6 +1900,12 @@
WebSocket服务端地址<para>请记得带端口号</para> WebSocket服务端地址<para>请记得带端口号</para>
</summary> </summary>
</member> </member>
<member name="M:AuroraNative.WebSockets.Client.#ctor(AuroraNative.Event)">
<summary>
创建一个 <see cref="T:AuroraNative.WebSockets.Client"/> 实例
</summary>
<param name="Event">重写后的事件类实例</param>
</member>
<member name="M:AuroraNative.WebSockets.Client.Create"> <member name="M:AuroraNative.WebSockets.Client.Create">
<summary> <summary>
创建并连接到WebSocket服务器 创建并连接到WebSocket服务器
@@ -1863,6 +1927,12 @@
WebSocket监听端口 WebSocket监听端口
</summary> </summary>
</member> </member>
<member name="M:AuroraNative.WebSockets.Server.#ctor(AuroraNative.Event)">
<summary>
创建一个 <see cref="T:AuroraNative.WebSockets.Server"/> 实例
</summary>
<param name="Event">重写后的事件类实例</param>
</member>
<member name="M:AuroraNative.WebSockets.Server.Create"> <member name="M:AuroraNative.WebSockets.Server.Create">
<summary> <summary>
创建WebSocket服务器并监听端口 创建WebSocket服务器并监听端口

View File

@@ -1,4 +1,5 @@
using AuroraNative.EventArgs; using AuroraNative.EventArgs;
using AuroraNative.WebSockets;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
namespace AuroraNative namespace AuroraNative

110
AuroraNative/Logger.cs Normal file
View File

@@ -0,0 +1,110 @@
using System;
namespace AuroraNative
{
/// <summary>
/// 彩色日志输出类
/// </summary>
public static class Logger
{
#region ----
/// <summary>
/// 日志级别设定<para>默认 Info</para>
/// </summary>
public static LogLevel LogLevel = LogLevel.Info;
#endregion
#region ----
/// <summary>
/// 输出一个等级为 调试 的信息
/// </summary>
/// <param name="Message">要输出的信息</param>
/// <param name="MethodName">输出的方法名,可选传入</param>
public static void Debug(string Message, string MethodName = null) {
if (LogLevel <= LogLevel.Debug) {
Output(Message, ConsoleColor.Gray, LogLevel.Debug, MethodName);
}
}
/// <summary>
/// 输出一个等级为 信息 的信息
/// </summary>
/// <param name="Message">要输出的信息</param>
/// <param name="MethodName">输出的方法名,可选传入</param>
public static void Info(string Message, string MethodName = null)
{
if (LogLevel <= LogLevel.Info)
{
Output(Message, ConsoleColor.White, LogLevel.Info, MethodName);
}
}
/// <summary>
/// 输出一个等级为 警告 的信息
/// </summary>
/// <param name="Message">要输出的信息</param>
/// <param name="MethodName">输出的方法名,可选传入</param>
public static void Warning(string Message, string MethodName = null)
{
if (LogLevel <= LogLevel.Warning)
{
Output(Message, ConsoleColor.Yellow, LogLevel.Warning, MethodName);
}
}
/// <summary>
/// 输出一个等级为 错误 的信息
/// </summary>
/// <param name="Message">要输出的信息</param>
/// <param name="MethodName">输出的方法名,可选传入</param>
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
}
/// <summary>
/// 表示日志信息等级的枚举
/// </summary>
public enum LogLevel {
/// <summary>
/// 表示输出日志的等级是 "调试" 级别
/// </summary>
Debug = 0,
/// <summary>
/// 表示输出日志的等级是 "信息" 级别
/// </summary>
Info = 1,
/// <summary>
/// 表示输出日志的等级是 "警告" 级别
/// </summary>
Warning = 2,
/// <summary>
/// 表示输出日志的等级是 "错误" 级别
/// </summary>
Error = 3
}
}

View File

@@ -17,15 +17,8 @@ namespace AuroraNative.WebSockets
{ {
#region ---- #region ----
/// <summary>
/// Websocket句柄
/// </summary>
internal WebSocket WebSocket; internal WebSocket WebSocket;
/// <summary> internal Event EventHook;
/// 事件钩子
/// </summary>
public Event EventHook;
internal JObject Json; internal JObject Json;
internal static Type[] AttributeTypes; internal static Type[] AttributeTypes;

View File

@@ -34,6 +34,12 @@ namespace AuroraNative.WebSockets
AttributeTypes = Assembly.GetExecutingAssembly().GetTypes().Where(p => p.IsAbstract == false && p.IsInterface == false && typeof(Attribute).IsAssignableFrom(p)).ToArray(); AttributeTypes = Assembly.GetExecutingAssembly().GetTypes().Where(p => p.IsAbstract == false && p.IsInterface == false && typeof(Attribute).IsAssignableFrom(p)).ToArray();
} }
/// <summary>
/// 创建一个 <see cref="Client"/> 实例
/// </summary>
/// <param name="Event">重写后的事件类实例</param>
public Client(Event Event) => EventHook = Event;
#endregion #endregion
#region ---- #region ----
@@ -43,16 +49,32 @@ namespace AuroraNative.WebSockets
/// </summary> /// </summary>
public bool Create() public bool Create()
{ {
WebSocket = new ClientWebSocket(); Logger.Debug("正向WebSocket已创建准备连接...", $"{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}");
if (WebSocket is ClientWebSocket socket) { for (int i = 1;i < 4;i++) {
Task Connect = socket.ConnectAsync(new Uri("ws://" + Host + "/"), CancellationToken.None); try
Connect.Wait();
if (WebSocket.State == WebSocketState.Open)
{ {
Task.Run(Feedback); WebSocket = new ClientWebSocket();
return true; 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; return false;
} }
@@ -61,8 +83,17 @@ namespace AuroraNative.WebSockets
/// </summary> /// </summary>
public void Dispose() public void Dispose()
{ {
WebSocket.Dispose(); Logger.Debug($"准备销毁正向WebSocket...", $"{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}");
WebSocket.Abort(); 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 #endregion

View File

@@ -38,6 +38,12 @@ namespace AuroraNative.WebSockets
AttributeTypes = Assembly.GetExecutingAssembly().GetTypes().Where(p => p.IsAbstract == false && p.IsInterface == false && typeof(Attribute).IsAssignableFrom(p)).ToArray(); AttributeTypes = Assembly.GetExecutingAssembly().GetTypes().Where(p => p.IsAbstract == false && p.IsInterface == false && typeof(Attribute).IsAssignableFrom(p)).ToArray();
} }
/// <summary>
/// 创建一个 <see cref="Server"/> 实例
/// </summary>
/// <param name="Event">重写后的事件类实例</param>
public Server(Event Event) => EventHook = Event;
#endregion #endregion
#region ---- #region ----
@@ -47,13 +53,22 @@ namespace AuroraNative.WebSockets
/// </summary> /// </summary>
public void Create() public void Create()
{ {
Listener = new HttpListener(); try
Listener.Prefixes.Add("http://*:" + Port + "/");
Listener.Start();
Task.Run(Feedback);
while (!IsConnect)
{ {
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
/// </summary> /// </summary>
public void Dispose() public void Dispose()
{ {
Listener.Stop(); Logger.Debug($"准备销毁反向WebSocket...", $"{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}");
WebSocket.Dispose(); try {
WebSocket.Abort(); 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 #endregion
@@ -78,9 +100,11 @@ namespace AuroraNative.WebSockets
HttpListenerContext Context = await Listener.GetContextAsync(); HttpListenerContext Context = await Listener.GetContextAsync();
if (Context.Request.IsWebSocketRequest) if (Context.Request.IsWebSocketRequest)
{ {
Logger.Info("收到来自 go-cqhttp 客户端的连接!连接已建立!");
HttpListenerWebSocketContext SocketContext = await Context.AcceptWebSocketAsync(null); HttpListenerWebSocketContext SocketContext = await Context.AcceptWebSocketAsync(null);
WebSocket = SocketContext.WebSocket; WebSocket = SocketContext.WebSocket;
IsConnect = true; IsConnect = true;
Api.Create(this);
while (WebSocket.State == WebSocketState.Open) while (WebSocket.State == WebSocketState.Open)
{ {
await GetEventAsync(); await GetEventAsync();

View File

@@ -39,9 +39,15 @@
- 优化内部算法或修改类型如将返回的JObject类型抽象为新自定义类型 - vX.X.X+1 - 优化内部算法或修改类型如将返回的JObject类型抽象为新自定义类型 - vX.X.X+1
- 重命名/删除/新增 文件/命名空间/API - vX.X+1.X - 重命名/删除/新增 文件/命名空间/API - vX.X+1.X
## 文档
开发文档:[点我查看](https://auroranative.mikuy.cn)
> 开发文档是与框架一起更新的,因此文档也处于快速迭代状态。
## 兼容性 ## 兼容性
### 接口 ### 通讯方式
- [ ] HTTP API - [ ] HTTP API
- [ ] 反向 HTTP POST - [ ] 反向 HTTP POST
@@ -50,7 +56,7 @@
## 关于 ISSUE ## 关于 ISSUE
如果没有大问题请到 Discussions 处提问 如果没有大问题请到 [Discussions](https://github.com/timi137137/AuroraNative/discussions) 处提问
以下 ISSUE 会被直接关闭 以下 ISSUE 会被直接关闭