C#实现热更新服务器程序

转自:掘金

很早就想写一篇关于热更服务器的文章,这两天有功夫就来写一下,正巧前两天也花时间把自己写了一段时间的C#框架给整理开源了。

热更新有没有解决一些开发问题的痛点

其实首先探讨的一个问题就是,热更服务器程序到底有没有必要出现,或者说有没有适用场景,我个人觉得吧还是有的。

如果真的可以在不重启应用的情况下实现逻辑的更新,这未尝对于一些紧急的情况不是一个好消息,尤其是一些小团队、小创业公司刚起步的时候,技术测试流程和人力不会像成规模的企业那样完善,那么带来的问题就是上线后的应用、游戏可能会存在一些Bug,如果不严重还好,可以留到下一个迭代更新统一修复,但是如果严重了,又考虑如果此刻关服修复会导致用户流失,那么这时候不停服热更新就有了应用场景,可以在用户无感知的情况下进行逻辑的修复工作。这也是热更功能主要的适用场景,至于增加新功能或者删除一些功能也可以通过不停服的方式来操作。

那么说完这个需求后,接下就是怎么才能实现这个功能。其实这个功能主要还是利用了C#自带的反射,在新的Dotnet框架中.net core3.0以后和.net5.0以后,微软对Assembly加载做了进一步整理,虽然以前也有类似功能,但是众所周知的原因,以前的.net版本混乱,现在微软既开源也统一化版本,可以说在未来时间里,.Net的潜力不可估量,那么我所讲的,也是基于较新的框架版本实现的。

热更新实现原理

AssemblyLoadContext 这个类就是今天的主角,它的主要功能就是隔离式的程序上下文,什么意思,就是它具备一定保护,可以使动态加载的程序集不和静态加载的程序集混合在一起,而是独立运行在类似沙盒的空间里,但是又具备相互访问的权限。这就很厉害了,这样一来,我们可以加载自己的程序集,然后供本来应用调用,在需要更新的时候,把新的程序集加载进来,并且替换旧的程序,释放旧的程序集,这样就可以无缝衔接的执行新的逻辑了。

下面我就借用我自己写的框架来实现这个热更的过程,如果对热更原理本身感兴趣的,也可以去看看我写的热更源码,我会在文章最下面贴上我的开源项目地址,源码里面基本上都是有注释的,所以看起来也不会很难。

具体的实现过程

  • 首先我们创建一个.Net5.0或者.Netcore3.1的项目,取名Abc。

  • 创建成功,我们找到依懒项,右击管理Nuget程序包,选择浏览标签搜索:EasySharpFrame,然后选中后点击下载按钮进行安装。

  • 安装完成后,框架就算成功安装好了,接下来,我们再从解决方案右击新建一个新的项目,这个项目就是用于热更逻辑实现的动态库,名字就叫Hotfix,创建之后,在解决方案资源管理器一栏中就会看到这个项目已经成功添加进去了,之后我们右击这个Hotfix项目的依赖项,找到添加项目引用,直接把 Abc 勾选确定,至此项目的添加创建步骤就完成了。

  • 接下来就是开始写代码实际应用了,首先在Abc主项目中的Program.cs入口中,调用框架中热更管理单例。因为我们没有更改Hotfix项目的默认配置,所以生成出来的Dll文件名就是Hotfix,然后我们在Hotfix项目里添加一个Main.cs的入口文件,这里通过热更管理器就完成了初始化,后面每次重载也只需要重复这个步骤就可以了。

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
    
            // 确保进行不会自动结束
            while (true)
            {
                // 调用热更模块加载Hotfix
                HotfixMgr.Instance.Load("Hotfix", "Hotfix.Main");
                // 回车继续,否则阻塞
                Console.ReadLine();
            }
        }
    }
    复制代码
  • 接下来,我们在Hotfix项目里Main.cs中加点测试内容。

    public class Main
    {
        public void Hello()
        {
            Console.WriteLine("Hello World");
        }
    }
    复制代码
  • 并且在刚刚主工程代码里加点东西。

    // 调用热更模块加载Hotfix
    HotfixMgr.Instance.Load("Hotfix", "Hotfix.Main");
    // 这里可以通过Agent调用测试入口的函数
    HotfixMgr.Instance.Agent.Hello();
    // 回车继续,否则阻塞
    Console.ReadLine();
    复制代码
  • 这样一个简单的热更事例就完成了,接下来生成解决方案。然后找到Hotfix项目生成路径,把关于Hotfix.dll和Hotfix.pdb两个文件复制粘贴到Abc的生成路径下。双击Abc.exe,启动事例查看结果。注:pdb是用于给运行时提供出错时准确提示错误的解释文件,实际运行只需要dll,如果不需要查看问题出处,可以只复制dll即可。

  • 此时不要关闭控制台,继续回到VS中,修改一下Main.cs的内容,并且这次只生成Hotfix项目,把生成好的dll和pdb复制到Abc中。

    public class Main
    {
        public void Hello()
        {
            // 修改前
            // Console.WriteLine("Hello World");
            // 修改后
            Console.WriteLine("Hello New World");
        }
    }
    复制代码
  • 替换完成后,在控制台回车一下,结果显示,新的逻辑已经更新至程序中。

以上就是一个简单的热更流程展示,框架提供的热更功能还有更多功能,这里只是简单介绍一下热更的原理与实现。如果对框架感兴趣的朋友可以到github上去了解。

github:GitHub - suxf/EasySharpFrame: Easy .NET Develop Frame.


作者:枫叶不太红
链接:https://juejin.cn/post/6982433159258472485
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
要通过 C# 实现 Modbus RTU 服务器程序,可以按照以下步骤进行: 1. 引入 Modbus RTU 库:C# 有很多 Modbus RTU 库可以选择,比如 NModbus,ModbusTCP.Net 等。这些库提供了 Modbus RTU 的实现,包括解析请求、生成响应等。 2. 建立串口连接:使用 SerialPort 类建立串口连接。 3. 建立 TCP 服务器:使用 TcpListener 类建立一个 TCP 服务器,监听客户端的连接请求。 4. 实现 Modbus RTU 响应:当客户端连接上服务器后,服务器需要解析客户端发送的 Modbus RTU 请求,并生成对应的响应。 5. 发送响应到客户端:使用 NetworkStream 类将响应数据通过 Socket 发送给客户端。 6. 关闭连接:在通信结束后,服务器需要关闭连接,释放资源。 以下是一个简单的 C# Modbus RTU 服务器程序示例: ``` using System; using System.IO.Ports; using System.Net; using System.Net.Sockets; using Modbus.Data; using Modbus.Device; class Program { static void Main(string[] args) { // 创建串口连接 var serialPort = new SerialPort("COM1"); serialPort.BaudRate = 9600; serialPort.Parity = Parity.None; serialPort.DataBits = 8; serialPort.StopBits = StopBits.One; serialPort.Open(); // 创建 Modbus RTU 服务器 var modbusSlave = ModbusSerialSlave.CreateRtu(1, serialPort); modbusSlave.DataStore = DataStoreFactory.CreateDefaultDataStore(); modbusSlave.ListenAsync().Wait(); // 创建 TCP 服务器 var tcpListener = new TcpListener(IPAddress.Any, 502); tcpListener.Start(); while (true) { // 等待客户端连接 var client = tcpListener.AcceptTcpClient(); var stream = client.GetStream(); // 创建 Modbus RTU 设备 var modbusDevice = ModbusIpMaster.CreateRtu(modbusSlave); while (client.Connected) { try { // 读取请求数据 var frame = ModbusTcpFrame.ReadRequest(stream); // 解析请求数据 var request = frame.CreateRequest(); // 处理请求并生成响应数据 var response = modbusDevice.Execute(request); // 发送响应数据 response.Write(stream); } catch (Exception ex) { // 处理异常 } } // 关闭连接 stream.Close(); client.Close(); } } } ``` 需要注意的是,以上示例代码仅为演示用途,实际使用时需要结合具体的场景进行优化和修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值