ECSharp
Easy .NET Develop Frame.
Install / Use
/learn @suxf/ECSharpREADME
ECSharp (原:EasySharpFrame)
Easy .NET Develop Frame.
这是一个基于.Net语言框架而设计的开发框架。集成了许多常规用到的开发功能,主要目的是利于基于此框架的服务器快捷开发!
快速使用
可以直接从NuGet库中搜索安装最新版本。
版本支持
| 版本 | .Net6.0 | .Net5.0 | .NetCore3.1 | .NetFramework4.6.2 | .NetStandard2.0 | | :-: | :-----: | :-----: |:----------: | :----------------: | :------------: | | 1.17 | √ | √ | √ | √ | √ | | 1.13 | √ | √ | √ | × | × | | 1.11 | √ | √ | √ | √ | × |
更新历史 查看
目录介绍
| 目录 | 备注 | | ------------ | ------------ | | UnityESF | Unity框架支持 | | docs | 在线API文档 | | ES | 框架主工程 | | Sample | 框架测试样本工程 | | SampleDll | 框架热更模块测试样本工程 |
功能说明
1.HTTP服务
对TcpListener进行封装,支持ssl模式,可以完成高并发任务。以后可能会更新静态文件的访问,即网页访问。
/* 使用方法一 */
public void Http1()
{
// 先继承http异常接口,这里把测试的访问函数也写在一个类中,实际不需要
HttpHandle1 handle = new HttpHandle1();
// 建立http访问器,并载入异常接口类
HttpVisitor visitor = new HttpVisitor(handle);
// 建立http服务,填写地址并且赋予访问器
// X509Certificate2 certificate = new X509Certificate2("https.pfx", "8888");
// HttpService service = new HttpService("127.0.0.1", 8080, visitor, certificate);
HttpService service = new HttpService("127.0.0.1", 8080, visitor);
// 给访问器增加函数
visitor.Add("", handle.Index);
visitor.Add("Hello", handle.Hello);
// 启动服务
service.StartServer();
// 然后就可以通过浏览器或其他请求工具来访问了
// 访问地址: http://127.0.0.1:8080/Hello?text=World
Console.ReadLine();
}
class HttpHandle1 : IHttpVisitor
{
public void Index(HttpRequest request, HttpResponse response)
{
// 首页根访问
if (!request.GetParams.TryGetValue("text", out var text)) text = "text no content";
response.Write("Index:" + text);
}
public void Hello(HttpRequest request, HttpResponse response)
{
response.Write("Hello World:" + request.PostValue);
}
public void HttpVisitorException(HttpRequest request, Exception ex)
{
// http异常处理
}
}
/* 使用方法二 */
public void Http2()
{
// 先继承http异常接口,这里把测试的访问函数也写在一个类中,实际不需要
HttpHandle2 handle = new HttpHandle2();
// 建立http服务,填写地址
HttpService service = new HttpService("127.0.0.1", 8080, handle);
// 启动服务
service.StartServer();
// 然后就可以通过浏览器或其他请求工具来访问了
// 访问地址: http://127.0.0.1:8080/Hello?text=World
Console.ReadLine();
}
class HttpHandle2 : IHttp
{
public void HttpException(HttpRequest request, Exception exception)
{
// http异常处理
}
public void OnRequest(HttpRequest request, HttpResponse response)
{
// 这里是全部消息回调接口
// 所以如果需要高度自定义可以使用此方法
}
}
2.Websocket服务
使用Fleck库中的Websocket进行二次封装,支持ssl模式。
WebsocketService service = new WebsocketService("ws://127.0.0.1:8081", new WebsocketHandle());
class WebsocketHandle : IWebsocket
{
public void OnBinary(RemoteConnection conn)
{
// 数据使用byte流传输调用
}
public void OnClose(RemoteConnection conn)
{
// 关闭时调用
}
public void OnError(RemoteConnection conn, Exception exception)
{
// 出现异常调用
}
public void OnMessage(RemoteConnection conn)
{
// 数据使用文本时调用
}
public void OnOpen(RemoteConnection conn)
{
// 新连接产生调用
}
}
3.HyperSocket<自定义Socket服务>
该模块已经深度封装了原生Socket模块,实现了快捷连接,加密连接等比较便捷实用的功能,通过IOCP接口可以实现高并发收发。需要配合配套的客户端才能使用。
// 创建服务器
var config = new HyperSocketConfig() { UseSSL = true };
new HyperSocketServer("127.0.0.1", 8888, 500, new ServerListener(), config).StartServer();
// 服务器监听接口
class ServerListener : IHyperSocketServer
{
public void OnClose(RemoteHyperSocket socket)
{
// 客户端关闭
}
public void SocketError(RemoteHyperSocket socket, Exception ex)
{
// 连接异常
}
public void OnOpen(RemoteHyperSocket socket)
{
// 客户端新连接
}
public void OnTcpReceive(byte[] data, RemoteHyperSocket socket)
{
// Tcp模式接收
}
public void OnUdpReceive(byte[] data, RemoteHyperSocket socket)
{
// Udp模式接收
}
}
// 创建客户端
new HyperSocket("127.0.0.1", 8888, new ClientListener()).Connect();
// 客户端监听接口
class ClientListener : IHyperSocketClient
{
public void SocketError(HyperSocket socket, Exception ex)
{
// 客户端异常
}
public void OnOpen(HyperSocket socket)
{
// 客户端连接成功
}
public void OnTcpReceive(byte[] data, HyperSocket socket)
{
// Tcp模式接收
}
public void OnUdpReceive(byte[] data, HyperSocket socket)
{
// Udp模式接收
}
}
4.TimeFlow<时间流>
该模块深度封装了原生Thread模块,可以快捷给每个类增加一个时间更新,类似Unity中组件的Update功能,模块以固定周期的速度进行刷新,并且经过多个项目及测试,在周期时间内最终循环时间很精准。另外 TimeCaller 是支持快速定制一个Scheduler定时器的功能类;TimeClock是一种可自定义现实时间的闹钟定时器功能。
class TimeDemo : ITimeUpdate
{
TimeFlow tf;
public TimeDemo(){
// 时间流
tf = TimeFlow.Create(this);
tf.Start();
// 时间闹钟
TimeClock.Create(delegate(DateTime time) {
Log.Info($"Time Now Alarm Clock:{time}");
}, "00:00:00").Start(true);
// 时间执行器
TimeCaller.Create(static delegate {
Log.Info("Hello TimeCaller");
}, 2000, 1000, 3).Start();
}
// 可以从 TimeFlow.period 直接获取周期时间
// dt为消耗时间的差值 因为程序不可能每次都精准执行
// 所以update会不断调整时间执行时间 dt就是这个时间的差值
// 一般情况下不需要管理,因为在总时间循环中 几乎可以忽略 因为我们有自动修正
public void Update(int dt)
{
}
// 停止更新
public void UpdateEnd()
{
}
}
5.Sqlserver数据库助手
Sqlserver相关操作比较多,更多可直接查看Sample中书写的样例:查看链接
助手目前有以下几种功能:
- 数据库连接:简化连接操作步骤
- 数据库执行SQL和存储过程:书写SQL直接执行得到结果
- SQL语句构建器:函数化某些SQL关键字,通过函数连调实现执行SQL
- SQLServer基础配置加载器:可以通过映射关系加载数据库表中的配置,高并发读取
- Sqlserver数据缓存助理数据组:可以通过映射关系加载数据库表中的数据,高并发实现增删改查
- 非关系型存储:通过映射原理建立表中Key-Value模型的对象,实现高并发读写
// 数据库连接使用此函数即可简单创建 数据库的创建还提供更多重载方案,可以点入查看
SqlServerDbHelper dbHelper = new SqlServerDbHelper("127.0.0.1", "sa", "123456", "db_test");
// 增加异常监听器 需要一个继承 ISQLServerDBHelper 接口
dbHelper.SetExceptionListener(this);
// 检测数据库连接是否成功调用 成功返回true
if (dbHelper.CheckConnected())
{
Console.WriteLine("数据库已连接");
}
//获取数据库时间 如果获取不到默认获取程序本地时间
Log.Info("数据库时间:" + dbHelper.Now);
// 普通查询调用
var result = dbHelper.CommandSQL("SELECT * FROM tb_test");
// 查询条数判断
if (result.EffectNum > 0)
{
// 取出表一的相关数据
// 如果查询有多个select 可以通过result.dataSet取得
int id = (int)result.Collection[0]["id"];
Console.WriteLine($"id:{id}");
}
6.Mysql数据助手
Mysql数据助手和Sqlserver数据库助手使用操作差不多,可参考第5项。
// 数据库连接使用此函数即可简单创建 数据库的创建还提供更多重载方案,可以点入查看
MySqlDbHelper dbHelper = new MySqlDbHelper("127.0.0.1", "root", "123456");
// 增加异常监听器
dbHelper.SetExceptionListener(this);
// 检测数据库连接是否成功调用 成功返回true
if (dbHelper.CheckConnected())
{
Log.Info("数据库已连接");
}
//获取数据库时间 如果获取不到默认获取程序本地时间
Log.Info("数据库时间:" + dbHelper.Now);
7.Redis数据库助手
简化Redis连接复杂度,快速连接Redis并且对数据进行高并发读写操作,对订阅功能进行简化操作,使订阅更加易用。
// 继承 IRedisEvent 接口来用于监听回调
RedisHelper helper = new RedisHelper("127.0.0.1:6379");
// 增加事件监听用于检测连接状态
helper.AddEventListener(this);
// 设置一个值
helper.Set("test", 1);
// 取出值
var test = helper.Get<int>("test");
8.Log功能
日志功能就是解决服务器对各种记录数据的记录和输出,日志即可输出在控制窗口,也可以写入本地文件持久化储存,供后续查看。Log类中提供日志前置配置参数,可以对日志进行自定义配置,详见 LogConfig 类。
// 以下四个函数均为普通分级日志输出函数
Log.Debug("debug is this");
Log.Info("info is this");
Log.Warn("warn is this");
Log.Error("error is this");
// 此函数可以写在try catch中 用于打印异常问题
Log.Exception(new System.Exception(), "exception is this");
9.热更新功能
支持服务器运行中可以进行逻辑更新的功能。当然,热更的实现,在各个语言上都是通过运行时反射实现的,所以一旦利用反射原理的功能都会逊色于原生直接调用。经过多次测试在千万次的简单循环下,初次加载可能会存在总量30~100毫秒的延迟;随之以后的调用则影响很小,循环总量和直接调用总量为2:1,也就是说在正常情况下,直接调用耗时1ms的操作,移植到热更新层也仅仅花费2ms左右,所以非密集型计算,耗时偏差基本可以忽略不计。
/** 主工程项目 **/
class Test_Hotfix
{
public Test_Hotfix()
{
while (true)
{
// 普通测试
TestHotfix();
// 耗时测试
// ConsumeTime();
Console.WriteLine($"Is First Load:{HotfixMgr.IsFirstLoad}");
// 回车重载测试
Console.ReadLine();
Console.Clear();
}
}
// 测试只需要放入构造函数
// 热更测试
public void TestHotfix()
{
HotfixMgr.Load("SampleDll", "SampleDll.Main", new string[] { "Hello World" }, "Main_Test");
}
// 测试只需要放入构造函数
// 耗时测试
public void ConsumeTime()
{
HotfixMgr.Instance.Load("SampleDll", "SampleDll.Main", null, "Main_Test1");
Player player = new Player();
Stopwatch watch = new Stopwatch();
/* 性能测试 */
// 第一次直接调用
Console.WriteLine("第一次直接调用开始~");
watch.Reset();
watch.Start();
player.Test();
watch.Stop();
Console.WriteLine($"第一次直接调用耗时1:{watch.Elapsed.TotalMilliseconds}ms");
// 第一次实测热更调用
Console.WriteLine("\n\n热更调用开始~");
watch.Reset();
watch.Start();
player.GetDynamicAgent().Test();
watch.Stop();
Console.WriteLine($"第一次热更层耗时1:{watch.Elapsed.TotalMilliseconds}ms");
// 第二次直接调用
Console.WriteLine("\n\n第二次直接调用开始~");
watch.Reset();
watch.Start();
player.Test();
watch.Stop();
Console.WriteLine($"第二次直接调用耗时2:{watch.Elapsed.TotalMilliseconds}ms");
// 第二次实测热更调用
Console.WriteLine("\n\n热更调用开始~");
watch.R
Related Skills
node-connect
346.8kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
107.6kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
346.8kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
346.8kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
