本篇是 Http 服务器系列博文的第十篇,对应项目是 LiteHttp,具体可访问 http://dreamyouxi.com/litehttp.html。
Unity 引擎中 C# 脚本的运行环境是 Mono 平台,而非微软的 .NET,Unity 引擎本身大部分由 C++ 编写。
在 LiteHttp 项目中,原本已支持 Lua 脚本来书写动态网页。这里引入 C# 脚本,目的是辅助 C++ 端的开发工作。
把 C# 当脚本语言来使用,相比 Lua 优势更多,底层依然基于 C++ 构建。
环境搭建
step1:去 Mono 官网下载 msi 安装包,x64 和 x86 分别对应 64 位和 32 位 exe。
step2:编写 C# 与 C++ 测试代码。
C++ 端示例:
C# 端示例:
C++ 运行结果:
在 LiteHttpSvr 中的初步应用:文件系统
将原本 C++ 端的文件读取与缓存逻辑迁移到 C# 实现。
C++ 端的修改:
C# 端实现:
using System;
using System.Collections.Generic;
using System.IO;
namespace LiteHttpScript
{
class CppEntry
{
static string CallMain(string file)
{
try
{
//System.Console.WriteLine("[C# Handle]:" + file);
return FileCache.Handle(file);
}
catch (Exception e)
{
System.Console.WriteLine("Err:" + e.Message);
return "";
}
}
}
public class FileCache
{
static FileCacheImpl impl = new FileCacheImpl();
public static string Handle(string file)
{
lock (impl)
{
return impl.GetFile(file);
}
}
};
//sample LRU file cache which limited by memory
public class FileCacheImpl
{
class FileData
{
public string key;
public string data;
public DateTime lastModifyUTCTime;
}
public string GetFile(string file)
{
LinkedListNode<FileData> ret = null;
if (_cache.TryGetValue(file, out ret))
{
//has find cache
_list.Remove(ret);
_list.AddFirst(ret);
//check file will update or not
}
else
{
//missing cache
try
{
var data = new FileData();
var info = new FileInfo(file);
data.lastModifyUTCTime = info.LastWriteTimeUtc;
data.data = File.ReadAllText(file);
data.key = file;
ret = new LinkedListNode<FileData>(data);
_list.AddFirst(ret);
_cache.Add(file, ret);
_currentMemoryUseage += data.data.Length;
}
catch (Exception e)
{
//file not exist
return "";
}
}
while (_list.Count > 1 && _currentMemoryUseage >= MaxMenmoryCacheSize)
{
var tail = _list.Last;
_cache.Remove(tail.Value.Value.key);
_list.RemoveLast();
_currentMemoryUseage -= tail.Value.Value.data.Length;
}
//GC.Collect();
return ret.Value.data;
}
// private long MaxMenmoryCacheSize { get { return 104857600L; } }//最大缓存大小 100 MB
private long MaxMenmoryCacheSize { get { return 100L; } }//最大缓存大小 100 MB
// private long MaxCacheFileNum { get { return 1024; } }//最大文件缓存数量
private long _currentMemoryUseage = 0;
private Dictionary<string, LinkedListNode<FileData>> _cache = new Dictionary<string, LinkedListNode<FileData>>();
private LinkedList<LinkedListNode<FileData>> _list = new LinkedList<LinkedListNode<FileData>>();
};
}
输出结果:
关于脚本语言还可以具备的其他特性,比如热更新,C# 同样可以支持。