完善网络框架,增加服务器断开连接回调

This commit is contained in:
ALEXTANG
2023-07-18 17:36:48 +08:00
parent a473971cfb
commit 526baf45fa
39 changed files with 559 additions and 308 deletions

View File

@@ -16,9 +16,11 @@ namespace TEngine
// 解析命令行参数
Parser.Default.ParseArguments<CommandLineOptions>(Environment.GetCommandLineArgs())
.WithNotParsed(error => throw new Exception("Command line format error!"))
.WithParsed(option => Define.Options = option);
.WithParsed(option => AppDefine.Options = option);
// 加载框架配置
TEngineSettingsHelper.Initialize();
// 检查启动参数
switch (Define.Options.AppType)
switch (AppDefine.Options.AppType)
{
case AppType.Game:
{
@@ -31,12 +33,12 @@ namespace TEngine
}
default:
{
throw new NotSupportedException($"AppType is {Define.Options.AppType} Unrecognized!");
throw new NotSupportedException($"AppType is {AppDefine.Options.AppType} Unrecognized!");
}
}
// 根据不同的运行模式来选择日志的方式
switch (Define.Options.Mode)
switch (AppDefine.Options.Mode)
{
case Mode.Develop:
{
@@ -71,7 +73,7 @@ namespace TEngine
// 加载核心程序集
AssemblyManager.Initialize();
Log.Info($"Start Server Param => {Parser.Default.FormatCommandLine(Define.Options)}");
Log.Info($"Start Server Param => {Parser.Default.FormatCommandLine(AppDefine.Options)}");
}
catch (Exception exception)
{
@@ -81,7 +83,7 @@ namespace TEngine
public static async FTask Start()
{
switch (Define.Options.Mode)
switch (AppDefine.Options.Mode)
{
case Mode.Develop:
{
@@ -99,7 +101,7 @@ namespace TEngine
{
// 发布模式只会启动启动参数传递的Server、也就是只会启动一个Server
// 您可以做一个Server专门用于管理启动所有Server的工作
await Server.Create(Define.Options.AppId);
await Server.Create(AppDefine.Options.AppId);
return;
}
}

View File

@@ -0,0 +1,11 @@
#if TENGINE_NET
#pragma warning disable CS8618
namespace TEngine
{
public static class AppDefine
{
public static CommandLineOptions Options;
public static uint AppId => Options.AppId;
}
}
#endif

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: d9135b10424d287419b2b9b46caa803d
guid: e08a4791989b16843a924bf798cdaa34
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -1,11 +1,111 @@
#if TENGINE_NET
#pragma warning disable CS8618
namespace TEngine
namespace TEngine.Core;
public static class Define
{
public static class Define
#if TENGINE_NET
#region ProtoBuf
public static readonly char[] SplitChars = { ' ', '\t' };
/// <summary>
/// ProtoBuf文件夹
/// </summary>
public static string ProtoBufDirectory;
/// <summary>
/// 服务端生成文件夹
/// </summary>
public static string ProtoBufServerDirectory;
/// <summary>
/// 客户端生成文件夹
/// </summary>
public static string ProtoBufClientDirectory;
/// <summary>
/// 代码模板路径
/// </summary>
public static string ProtoBufTemplatePath;
#endregion
#region Excel
/// <summary>
/// 配置文件根目录
/// </summary>
public static string ExcelProgramPath;
/// <summary>
/// 版本文件Excel
/// </summary>
public static string ExcelVersionFile;
/// <summary>
/// 服务器代码生成文件夹
/// </summary>
public static string ExcelServerFileDirectory;
/// <summary>
/// 客户端代码生成文件夹
/// </summary>
public static string ExcelClientFileDirectory;
/// <summary>
/// 服务器二进制数据文件夹
/// </summary>
public static string ExcelServerBinaryDirectory;
/// <summary>
/// 客户端二进制数据文件夹
/// </summary>
public static string ExcelClientBinaryDirectory;
/// <summary>
/// 服务器Json数据文件夹
/// </summary>
public static string ExcelServerJsonDirectory;
/// <summary>
/// 客户端Json数据文件夹
/// </summary>
public static string ExcelClientJsonDirectory;
/// <summary>
/// 服务器自定义导出代码
/// </summary>
public static string ServerCustomExportDirectory;
/// <summary>
/// 客户端自定义导出代码
/// </summary>
public static string ClientCustomExportDirectory;
/// <summary>
/// 自定义导出代码存放的程序集
/// </summary>
public static string CustomExportAssembly;
/// <summary>
/// 导表支持的类型
/// </summary>
public static readonly HashSet<string> ColTypeSet = new HashSet<string>()
{
public static CommandLineOptions Options;
public static uint AppId => Options.AppId;
"", "0", "bool", "byte", "short", "ushort", "int", "uint", "long", "ulong", "float", "string", "AttrConfig",
"short[]", "int[]", "long[]", "float[]", "string[]"
};
/// <summary>
/// Excel生成代码模板的位置
/// </summary>
public static string ExcelTemplatePath;
/// <summary>
/// 代码模板
/// </summary>
public static string ExcelTemplate
{
get
{
return _template ??= File.ReadAllText(ExcelTemplatePath);
}
}
private static string _template;
#endregion
#region Network
public static int SessionIdleCheckerInterval;
public static int SessionIdleCheckerTimeout;
#endregion
#endif
}
#endif

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: e08a4791989b16843a924bf798cdaa34
guid: 607b7ddd55f4bc3488ce863ef43f9613
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -67,12 +67,12 @@ namespace TEngine
Scenes.Add(scene);
return scene;
}
public void CreateSession(string remoteAddress, NetworkProtocolType networkProtocolType, Action onConnectComplete, Action onConnectFail, int connectTimeout = 5000)
public void CreateSession(string remoteAddress, NetworkProtocolType networkProtocolType, Action onConnectComplete, Action onConnectFail,Action onConnectDisconnect, int connectTimeout = 5000)
{
var address = NetworkHelper.ToIPEndPoint(remoteAddress);
var clientNetworkComponent = GetComponent<ClientNetworkComponent>() ?? AddComponent<ClientNetworkComponent>();
clientNetworkComponent.Initialize(networkProtocolType, NetworkTarget.Outer);
clientNetworkComponent.Connect(address, onConnectComplete, onConnectFail, connectTimeout);
clientNetworkComponent.Connect(address, onConnectComplete, onConnectFail,onConnectDisconnect, connectTimeout);
Session = clientNetworkComponent.Session;
}
#else

View File

@@ -1,75 +0,0 @@
#if TENGINE_NET
namespace TEngine.Core;
public static class ExcelDefine
{
/// <summary>
/// 项目跟目录路径
/// </summary>
private const string ProjectPath = "../../..";
/// <summary>
/// 配置文件根目录
/// </summary>
public static string ProgramPath = $"{ProjectPath}/Config/Excel/";
/// <summary>
/// 版本文件Excel
/// </summary>
public static string ExcelVersionFile = $"{ProgramPath}Version.txt";
/// <summary>
/// 服务器代码生成文件夹
/// </summary>
public static string ServerFileDirectory = $"{ProjectPath}/Server/TEngine.Model/Generate/ConfigTable/Entity/";
/// <summary>
/// 客户端代码生成文件夹
/// </summary>
public static string ClientFileDirectory = $"{ProjectPath}/Client/Unity/Assets/Scripts/TEngine/TEngine.Model/Generate/ConfigTable/Entity/";
/// <summary>
/// 服务器二进制数据文件夹
/// </summary>
public static string ServerBinaryDirectory = $"{ProjectPath}/Config/Binary/";
/// <summary>
/// 客户端二进制数据文件夹
/// </summary>
public static string ClientBinaryDirectory = $"{ProjectPath}/Client/Unity/Assets/Bundles/Config/";
/// <summary>
/// 服务器Json数据文件夹
/// </summary>
public static string ServerJsonDirectory = $"{ProjectPath}/Config/Json/Server/";
/// <summary>
/// 客户端Json数据文件夹
/// </summary>
public static string ClientJsonDirectory = $"{ProjectPath}/Config/Json/Client/";
/// <summary>
/// 服务器自定义导出代码
/// </summary>
public static string ServerCustomExportDirectory = $"{ProjectPath}/Server/TEngine.Model/Generate/CustomExport/";
/// <summary>
/// 客户端自定义导出代码
/// </summary>
public static string ClientCustomExportDirectory = $"{ProjectPath}/Client/Unity/Assets/Scripts/TEngine/TEngine.Model/Generate/CustomExport/";
/// <summary>
/// 导表支持的类型
/// </summary>
public static readonly HashSet<string> ColTypeSet = new HashSet<string>()
{
"", "0", "bool", "byte", "short", "ushort", "int", "uint", "long", "ulong", "float", "string", "AttrConfig",
"short[]", "int[]", "long[]", "float[]", "string[]"
};
/// <summary>
/// Excel生成代码模板的位置
/// </summary>
public static string ExcelTemplatePath = $"{ProjectPath}/Config/Template/ExcelTemplate.txt";
/// <summary>
/// 代码模板
/// </summary>
public static string ExcelTemplate
{
get
{
return _template ??= File.ReadAllText(Path.Combine(Environment.CurrentDirectory, $"{ProjectPath}/Config/Template/ExcelTemplate.txt"));
}
}
private static string _template;
}
#endif

View File

@@ -32,7 +32,7 @@ public sealed class ExcelExporter
public ExcelExporter(ExportType exportType)
{
ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
var versionFilePath = ExcelDefine.ExcelVersionFile;
var versionFilePath = Define.ExcelVersionFile;
switch (exportType)
{
@@ -47,8 +47,8 @@ public sealed class ExcelExporter
File.Delete(versionFilePath);
}
FileHelper.ClearDirectoryFile(ExcelDefine.ServerFileDirectory);
FileHelper.ClearDirectoryFile(ExcelDefine.ClientFileDirectory);
FileHelper.ClearDirectoryFile(Define.ExcelServerFileDirectory);
FileHelper.ClearDirectoryFile(Define.ExcelClientFileDirectory);
break;
}
}
@@ -63,12 +63,12 @@ public sealed class ExcelExporter
private static void CustomExport()
{
// 清除文件夹
FileHelper.ClearDirectoryFile(ExcelDefine.ServerCustomExportDirectory);
FileHelper.ClearDirectoryFile(ExcelDefine.ClientCustomExportDirectory);
FileHelper.ClearDirectoryFile(Define.ServerCustomExportDirectory);
FileHelper.ClearDirectoryFile(Define.ClientCustomExportDirectory);
// 找到程序集
var assemblyLoadContext = new AssemblyLoadContext("ExporterDll", true);
var dllBytes = File.ReadAllBytes(Path.Combine(Environment.CurrentDirectory, "Logic.dll"));
var pdbBytes = File.ReadAllBytes(Path.Combine(Environment.CurrentDirectory, "Logic.pdb"));
var dllBytes = File.ReadAllBytes($"{Define.CustomExportAssembly}.dll");
var pdbBytes = File.ReadAllBytes($"{Define.CustomExportAssembly}.pdb");
var assembly = assemblyLoadContext.LoadFromStream(new MemoryStream(dllBytes), new MemoryStream(pdbBytes));
// 加载程序集
AssemblyManager.LoadAssembly(int.MaxValue, assembly);
@@ -95,7 +95,7 @@ public sealed class ExcelExporter
/// </summary>
private void Find()
{
var versionFilePath = ExcelDefine.ExcelVersionFile;
var versionFilePath = Define.ExcelVersionFile;
if(File.Exists(versionFilePath))
{
@@ -107,7 +107,7 @@ public sealed class ExcelExporter
_versionDic = new Dictionary<string, long>();
}
var dir = new DirectoryInfo(ExcelDefine.ProgramPath);
var dir = new DirectoryInfo(Define.ExcelProgramPath);
var excelFiles = dir.GetFiles("*", SearchOption.AllDirectories);
if (excelFiles.Length <= 0)
@@ -256,8 +256,8 @@ public sealed class ExcelExporter
continue;
}
if (!ExcelDefine.ColTypeSet.Contains(serverType) ||
!ExcelDefine.ColTypeSet.Contains(clientType))
if (!Define.ColTypeSet.Contains(serverType) ||
!Define.ColTypeSet.Contains(clientType))
{
Exporter.LogError($"配置表 {exportInfo.Name} {col} 列 [{colName}] 客户端类型 {clientType}, 服务端类型 {serverType} 不合法");
continue;
@@ -297,12 +297,12 @@ public sealed class ExcelExporter
writeToClassTask.Add(Task.Run(() =>
{
WriteToClass(excelTable.ServerColInfos, ExcelDefine.ServerFileDirectory, true);
WriteToClass(excelTable.ServerColInfos, Define.ExcelServerFileDirectory, true);
}));
writeToClassTask.Add(Task.Run(() =>
{
WriteToClass(excelTable.ClientColInfos, ExcelDefine.ClientFileDirectory, false);
WriteToClass(excelTable.ClientColInfos, Define.ExcelClientFileDirectory, false);
}));
Task.WaitAll(writeToClassTask.ToArray());
@@ -385,7 +385,7 @@ public sealed class ExcelExporter
}
}
var template = ExcelDefine.ExcelTemplate;
var template = Define.ExcelTemplate;
if (fileBuilder.Length > 0)
{
@@ -407,8 +407,8 @@ public sealed class ExcelExporter
private void ExportToBinary()
{
var exportToBinaryTasks = new List<Task>();
var dynamicServerAssembly = DynamicAssembly.Load(ExcelDefine.ServerFileDirectory);
var dynamicClientAssembly = DynamicAssembly.Load(ExcelDefine.ClientFileDirectory);
var dynamicServerAssembly = DynamicAssembly.Load(Define.ExcelServerFileDirectory);
var dynamicClientAssembly = DynamicAssembly.Load(Define.ExcelClientFileDirectory);
foreach (var (tableName, tableList) in _tables)
{
@@ -465,7 +465,7 @@ public sealed class ExcelExporter
if (serverDynamicInfo?.ConfigData != null)
{
var bytes = ProtoBufHelper.ToBytes(serverDynamicInfo.ConfigData);
var serverBinaryDirectory = ExcelDefine.ServerBinaryDirectory;
var serverBinaryDirectory = Define.ExcelServerBinaryDirectory;
if (!Directory.Exists(serverBinaryDirectory))
{
@@ -476,7 +476,7 @@ public sealed class ExcelExporter
if (serverDynamicInfo.Json.Length > 0)
{
var serverJsonDirectory = ExcelDefine.ServerJsonDirectory;
var serverJsonDirectory = Define.ExcelServerJsonDirectory;
using var sw = new StreamWriter(Path.Combine(serverJsonDirectory, $"{csName}Data.Json"));
sw.WriteLine("{\"List\":[");
sw.Write(serverDynamicInfo.Json.ToString());
@@ -487,7 +487,7 @@ public sealed class ExcelExporter
if (clientDynamicInfo?.ConfigData != null)
{
var bytes = ProtoBufHelper.ToBytes(clientDynamicInfo.ConfigData);
var clientBinaryDirectory = ExcelDefine.ClientBinaryDirectory;
var clientBinaryDirectory = Define.ExcelClientBinaryDirectory;
if (!Directory.Exists(clientBinaryDirectory))
{
@@ -498,7 +498,7 @@ public sealed class ExcelExporter
if (clientDynamicInfo.Json.Length > 0)
{
var clientJsonDirectory = ExcelDefine.ClientJsonDirectory;
var clientJsonDirectory = Define.ExcelClientJsonDirectory;
using var sw = new StreamWriter(Path.Combine(clientJsonDirectory, $"{csName}Data.Json"));
sw.WriteLine("{\"List\":[");
sw.Write(clientDynamicInfo.Json.ToString());

View File

@@ -16,7 +16,7 @@ public sealed class Exporter
public void Start()
{
Console.OutputEncoding = Encoding.UTF8;
var exportType = Define.Options.ExportType;
var exportType = AppDefine.Options.ExportType;
if (exportType != ExportType.None)
{
@@ -39,7 +39,7 @@ public sealed class Exporter
LogInfo("");
exportType = (ExportType) key;
LoadConfig();
// LoadConfig();
switch (exportType)
{
@@ -61,50 +61,52 @@ public sealed class Exporter
Environment.Exit(0);
}
private void LoadConfig()
{
const string settingsName = "TEngineSettings.json";
var currentDirectory = Directory.GetCurrentDirectory();
if (!File.Exists(Path.Combine(currentDirectory, settingsName)))
{
throw new FileNotFoundException($"not found {settingsName} in OutputDirectory");
}
var configurationRoot = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile(settingsName)
.Build();
// ProtoBuf文件所在的位置文件夹位置
ProtoBufDefine.ProtoBufDirectory = configurationRoot["Export:ProtoBufDirectory:Value"];
// ProtoBuf生成到服务端的文件夹位置
ProtoBufDefine.ServerDirectory = configurationRoot["Export:ProtoBufServerDirectory:Value"];
// ProtoBuf生成到客户端的文件夹位置
ProtoBufDefine.ClientDirectory = configurationRoot["Export:ProtoBufClientDirectory:Value"];
// ProtoBuf生成代码模板的位置
ProtoBufDefine.ProtoBufTemplatePath = configurationRoot["Export:ProtoBufTemplatePath:Value"];
// Excel配置文件根目录
ExcelDefine.ProgramPath = configurationRoot["Export:ExcelProgramPath:Value"];
// Excel版本文件的位置
ExcelDefine.ExcelVersionFile = configurationRoot["Export:ExcelVersionFile:Value"];
// Excel生成服务器代码的文件夹位置
ExcelDefine.ServerFileDirectory = configurationRoot["Export:ExcelServerFileDirectory:Value"];
// Excel生成客户端代码文件夹位置
ExcelDefine.ClientFileDirectory = configurationRoot["Export:ExcelClientFileDirectory:Value"];
// Excel生成服务器二进制数据文件夹位置
ExcelDefine.ServerBinaryDirectory = configurationRoot["Export:ExcelServerBinaryDirectory:Value"];
// Excel生成客户端二进制数据文件夹位置
ExcelDefine.ClientBinaryDirectory = configurationRoot["Export:ExcelClientBinaryDirectory:Value"];
// Excel生成服务器Json数据文件夹位置
ExcelDefine.ServerJsonDirectory = configurationRoot["Export:ExcelServerJsonDirectory:Value"];
// Excel生成客户端Json数据文件夹位置
ExcelDefine.ClientJsonDirectory = configurationRoot["Export:ExcelClientJsonDirectory:Value"];
// Excel生成代码模板的位置
ExcelDefine.ExcelTemplatePath = configurationRoot["Export:ExcelTemplatePath:Value"];
// 服务器自定义导出代码文件夹位置
ExcelDefine.ServerCustomExportDirectory = configurationRoot["Export:ServerCustomExportDirectory:Value"];
// 客户端自定义导出代码文件夹位置
ExcelDefine.ClientCustomExportDirectory = configurationRoot["Export:ClientCustomExportDirectory:Value"];
}
#if old
// private void LoadConfig()
// {
// const string settingsName = "TEngineSettings.json";
// var currentDirectory = Directory.GetCurrentDirectory();
//
// if (!File.Exists(Path.Combine(currentDirectory, settingsName)))
// {
// throw new FileNotFoundException($"not found {settingsName} in OutputDirectory");
// }
//
// var configurationRoot = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory())
// .AddJsonFile(settingsName)
// .Build();
// // ProtoBuf文件所在的位置文件夹位置
// ProtoBufDefine.ProtoBufDirectory = configurationRoot["Export:ProtoBufDirectory:Value"];
// // ProtoBuf生成到服务端的文件夹位置
// ProtoBufDefine.ServerDirectory = configurationRoot["Export:ProtoBufServerDirectory:Value"];
// // ProtoBuf生成到客户端的文件夹位置
// ProtoBufDefine.ClientDirectory = configurationRoot["Export:ProtoBufClientDirectory:Value"];
// // ProtoBuf生成代码模板的位置
// ProtoBufDefine.ProtoBufTemplatePath = configurationRoot["Export:ProtoBufTemplatePath:Value"];
// // Excel配置文件根目录
// ExcelDefine.ProgramPath = configurationRoot["Export:ExcelProgramPath:Value"];
// // Excel版本文件的位置
// ExcelDefine.ExcelVersionFile = configurationRoot["Export:ExcelVersionFile:Value"];
// // Excel生成服务器代码的文件夹位置
// ExcelDefine.ServerFileDirectory = configurationRoot["Export:ExcelServerFileDirectory:Value"];
// // Excel生成客户端代码文件夹位置
// ExcelDefine.ClientFileDirectory = configurationRoot["Export:ExcelClientFileDirectory:Value"];
// // Excel生成服务器二进制数据文件夹位置
// ExcelDefine.ServerBinaryDirectory = configurationRoot["Export:ExcelServerBinaryDirectory:Value"];
// // Excel生成客户端二进制数据文件夹位置
// ExcelDefine.ClientBinaryDirectory = configurationRoot["Export:ExcelClientBinaryDirectory:Value"];
// // Excel生成服务器Json数据文件夹位置
// ExcelDefine.ServerJsonDirectory = configurationRoot["Export:ExcelServerJsonDirectory:Value"];
// // Excel生成客户端Json数据文件夹位置
// ExcelDefine.ClientJsonDirectory = configurationRoot["Export:ExcelClientJsonDirectory:Value"];
// // Excel生成代码模板的位置
// ExcelDefine.ExcelTemplatePath = configurationRoot["Export:ExcelTemplatePath:Value"];
// // 服务器自定义导出代码文件夹位置
// ExcelDefine.ServerCustomExportDirectory = configurationRoot["Export:ServerCustomExportDirectory:Value"];
// // 客户端自定义导出代码文件夹位置
// ExcelDefine.ClientCustomExportDirectory = configurationRoot["Export:ClientCustomExportDirectory:Value"];
// }
#endif
public static void LogInfo(string msg)
{

View File

@@ -20,22 +20,22 @@ public abstract class ACustomExport : ICustomExport
{
case CustomExportType.Client:
{
if (!Directory.Exists(ExcelDefine.ClientCustomExportDirectory))
if (!Directory.Exists(Define.ClientCustomExportDirectory))
{
Directory.CreateDirectory(ExcelDefine.ClientCustomExportDirectory);
Directory.CreateDirectory(Define.ClientCustomExportDirectory);
}
File.WriteAllText($"{ExcelDefine.ClientCustomExportDirectory}/{fileName}", fileContent);
File.WriteAllText($"{Define.ClientCustomExportDirectory}/{fileName}", fileContent);
return;
}
case CustomExportType.Server:
{
if (!Directory.Exists(ExcelDefine.ServerCustomExportDirectory))
if (!Directory.Exists(Define.ServerCustomExportDirectory))
{
Directory.CreateDirectory(ExcelDefine.ServerCustomExportDirectory);
Directory.CreateDirectory(Define.ServerCustomExportDirectory);
}
File.WriteAllText($"{ExcelDefine.ServerCustomExportDirectory}/{fileName}", fileContent);
File.WriteAllText($"{Define.ServerCustomExportDirectory}/{fileName}", fileContent);
return;
}
}

View File

@@ -1,28 +0,0 @@
#if TENGINE_NET
namespace TEngine.Core;
public static class ProtoBufDefine
{
public static readonly char[] SplitChars = {' ', '\t'};
/// <summary>
/// 项目跟目录路径
/// </summary>
private const string ProjectPath = "../../..";
/// <summary>
/// ProtoBuf文件夹
/// </summary>
public static string ProtoBufDirectory = $"{ProjectPath}/Config/ProtoBuf/";
/// <summary>
/// 服务端生成文件夹
/// </summary>
public static string ServerDirectory = $"{ProjectPath}/Server/TEngine.Model/Generate/NetworkProtocol/";
/// <summary>
/// 客户端生成文件夹
/// </summary>
public static string ClientDirectory = $"{ProjectPath}/Client/Unity/Assets/Scripts/TEngine/TEngine.Model/Generate/NetworkProtocol/";
/// <summary>
/// 代码模板路径
/// </summary>
public static string ProtoBufTemplatePath = $"{ProjectPath}/Config/Template/ProtoTemplate.txt";
}
#endif

View File

@@ -39,14 +39,14 @@ public sealed class ProtoBufExporter
{
Console.OutputEncoding = Encoding.UTF8;
if (!Directory.Exists(ProtoBufDefine.ServerDirectory))
if (!Directory.Exists(Define.ProtoBufServerDirectory))
{
Directory.CreateDirectory(ProtoBufDefine.ServerDirectory);
Directory.CreateDirectory(Define.ProtoBufServerDirectory);
}
if (!Directory.Exists(ProtoBufDefine.ClientDirectory))
if (!Directory.Exists(Define.ProtoBufClientDirectory))
{
Directory.CreateDirectory(ProtoBufDefine.ClientDirectory);
Directory.CreateDirectory(Define.ProtoBufClientDirectory);
}
var tasks = new Task[2];
@@ -86,9 +86,9 @@ public sealed class ProtoBufExporter
_aRouteRequest = Opcode.OuterRouteRequest;
_aRouteResponse = Opcode.OuterRouteResponse;
opCodeName = "OuterOpcode";
protoFile = $"{ProtoBufDefine.ProtoBufDirectory}OuterMessage.proto";
saveDirectory.Add(ProtoBufDefine.ServerDirectory, _serverTemplate);
saveDirectory.Add(ProtoBufDefine.ClientDirectory, _clientTemplate);
protoFile = $"{Define.ProtoBufDirectory}OuterMessage.proto";
saveDirectory.Add(Define.ProtoBufServerDirectory, _serverTemplate);
saveDirectory.Add(Define.ProtoBufClientDirectory, _clientTemplate);
break;
}
case ProtoBufOpCodeType.Inner:
@@ -101,8 +101,8 @@ public sealed class ProtoBufExporter
_aRouteRequest = Opcode.InnerRouteRequest + 1000;
_aRouteResponse = Opcode.InnerRouteResponse + 1000;
opCodeName = "InnerOpcode";
protoFile = $"{ProtoBufDefine.ProtoBufDirectory}InnerMessage.proto";
saveDirectory.Add(ProtoBufDefine.ServerDirectory, _serverTemplate);
protoFile = $"{Define.ProtoBufDirectory}InnerMessage.proto";
saveDirectory.Add(Define.ProtoBufServerDirectory, _serverTemplate);
break;
}
case ProtoBufOpCodeType.InnerBson:
@@ -115,8 +115,8 @@ public sealed class ProtoBufExporter
_aRouteRequest = Opcode.InnerBsonRouteRequest + 1000;
_aRouteResponse = Opcode.InnerBsonRouteResponse + 1000;
opCodeName = "InnerBsonOpcode";
protoFile = $"{ProtoBufDefine.ProtoBufDirectory}InnerBsonMessage.proto";
saveDirectory.Add(ProtoBufDefine.ServerDirectory, _serverTemplate);
protoFile = $"{Define.ProtoBufDirectory}InnerBsonMessage.proto";
saveDirectory.Add(Define.ProtoBufServerDirectory, _serverTemplate);
break;
}
}
@@ -143,7 +143,7 @@ public sealed class ProtoBufExporter
isMsgHead = true;
opcodeInfo = new OpcodeInfo();
file.AppendLine("\t[ProtoContract]");
className = currentLine.Split(ProtoBufDefine.SplitChars, StringSplitOptions.RemoveEmptyEntries)[1];
className = currentLine.Split(Define.SplitChars, StringSplitOptions.RemoveEmptyEntries)[1];
var splits = currentLine.Split(new[] {"//"}, StringSplitOptions.RemoveEmptyEntries);
if (splits.Length > 1)
@@ -337,7 +337,7 @@ public sealed class ProtoBufExporter
private async Task RouteType()
{
var routeTypeFile = $"{ProtoBufDefine.ProtoBufDirectory}RouteType.Config";
var routeTypeFile = $"{Define.ProtoBufDirectory}RouteType.Config";
var protoFileText = await File.ReadAllTextAsync(routeTypeFile);
var routeTypeFileSb = new StringBuilder();
routeTypeFileSb.AppendLine("namespace TEngine.Core.Network\n{");
@@ -369,8 +369,8 @@ public sealed class ProtoBufExporter
routeTypeFileSb.AppendLine("\t}\n}");
var file = routeTypeFileSb.ToString();
await File.WriteAllTextAsync($"{ProtoBufDefine.ServerDirectory}RouteType.cs", file);
await File.WriteAllTextAsync($"{ProtoBufDefine.ClientDirectory}RouteType.cs", file);
await File.WriteAllTextAsync($"{Define.ProtoBufServerDirectory}RouteType.cs", file);
await File.WriteAllTextAsync($"{Define.ProtoBufClientDirectory}RouteType.cs", file);
}
private void Repeated(StringBuilder file, string newline)
@@ -379,7 +379,7 @@ public sealed class ProtoBufExporter
{
var index = newline.IndexOf(";", StringComparison.Ordinal);
newline = newline.Remove(index);
var property = newline.Split(ProtoBufDefine.SplitChars, StringSplitOptions.RemoveEmptyEntries);
var property = newline.Split(Define.SplitChars, StringSplitOptions.RemoveEmptyEntries);
var type = property[1];
var name = property[2];
var memberIndex = int.Parse(property[4]);
@@ -400,7 +400,7 @@ public sealed class ProtoBufExporter
{
var index = currentLine.IndexOf(";", StringComparison.Ordinal);
currentLine = currentLine.Remove(index);
var property = currentLine.Split(ProtoBufDefine.SplitChars, StringSplitOptions.RemoveEmptyEntries);
var property = currentLine.Split(Define.SplitChars, StringSplitOptions.RemoveEmptyEntries);
var type = property[0];
var name = property[1];
var memberIndex = int.Parse(property[3]);
@@ -451,7 +451,7 @@ public sealed class ProtoBufExporter
private void LoadTemplate()
{
string[] lines = File.ReadAllLines(ProtoBufDefine.ProtoBufTemplatePath, Encoding.UTF8);
string[] lines = File.ReadAllLines(Define.ProtoBufTemplatePath, Encoding.UTF8);
StringBuilder serverSb = new StringBuilder();
StringBuilder clientSb = new StringBuilder();

View File

@@ -34,12 +34,12 @@ namespace TEngine
private bool CheckLogLevel(int level)
{
if (Define.Options == null)
if (AppDefine.Options == null)
{
return true;
}
return Define.Options.LogLevel <= level;
return AppDefine.Options.LogLevel <= level;
}
public void Trace(string msg)

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 37d561d4e0b69c2489c4f54813f740e1
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 62fb06b1efb2c3e4cb58e2bc0119688d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,63 @@
#if TENGINE_UNITY
using TEngine.Core;
using TEngine.Core.Network;
namespace TEngine.Logic
{
public class SessionHeartbeatComponent : Entity
{
private long _timerId;
private long _selfRunTimeId;
private Session _session;
private readonly PingRequest _pingRequest = new PingRequest();
public int Ping { get; private set; }
public override void Dispose()
{
Stop();
Ping = 0;
_session = null;
_selfRunTimeId = 0;
base.Dispose();
}
public void Start(int interval)
{
_session = (Session)Parent;
_selfRunTimeId = RuntimeId;
_timerId = TimerScheduler.Instance.Unity.RepeatedTimer(interval, () => RepeatedSend().Coroutine());
}
public void Stop()
{
if (_timerId == 0)
{
return;
}
TimerScheduler.Instance?.Unity.RemoveByRef(ref _timerId);
}
private async FTask RepeatedSend()
{
if (_selfRunTimeId != RuntimeId)
{
Stop();
}
var requestTime = TimeHelper.Now;
var pingResponse = (PingResponse)await _session.Call(_pingRequest);
if (pingResponse.ErrorCode != 0)
{
return;
}
var responseTime = TimeHelper.Now;
Ping = (int)(responseTime - requestTime) / 2;
TimeHelper.TimeDiff = pingResponse.Now + Ping - responseTime;
}
}
}
#endif

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 0dac52ee40f938641a63d624ff19dd3f
guid: a99afa40336b6ab4b8f1935689ff27c1
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -0,0 +1,58 @@
#if TENGINE_NET
using TEngine.Core.Network;
namespace TEngine.Core;
public class SessionIdleCheckerComponent: Entity
{
private long _timeOut;
private long _timerId;
private long _selfRuntimeId;
private Session _session;
public override void Dispose()
{
Stop();
_timeOut = 0;
_selfRuntimeId = 0;
_session = null;
base.Dispose();
}
public void Start(int interval, int timeOut)
{
_timeOut = timeOut;
_session = (Session)Parent;
_selfRuntimeId = RuntimeId;
_timerId = TimerScheduler.Instance.Core.RepeatedTimer(interval, Check);
}
public void Stop()
{
if (_timerId == 0)
{
return;
}
TimerScheduler.Instance.Core.RemoveByRef(ref _timerId);
}
private void Check()
{
if (_selfRuntimeId != RuntimeId)
{
Stop();
}
var timeNow = TimeHelper.Now;
if (timeNow - _session.LastReceiveTime < _timeOut)
{
return;
}
Log.Warning($"session timeout id:{Id}");
_session.Dispose();
}
}
#endif

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: d418e7f4b6646504c8a6ca4b381992b0
guid: d8ecddd8867e88f409286a99647a236c
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -4,17 +4,24 @@ using System.Net;
namespace TEngine.Core.Network
{
public abstract class AClientNetwork : ANetwork
public abstract class AClientNetwork: ANetwork
{
public uint ChannelId { get; protected set; }
public abstract event Action OnDispose;
public abstract event Action OnConnectFail;
public abstract event Action OnConnectComplete;
public abstract event Action OnConnectDisconnect;
public abstract event Action<uint> OnChangeChannelId;
public abstract event Action<APackInfo> OnReceiveMemoryStream;
protected AClientNetwork(Scene scene, NetworkType networkType, NetworkProtocolType networkProtocolType, NetworkTarget networkTarget) : base(scene, networkType, networkProtocolType, networkTarget) { }
protected AClientNetwork(Scene scene, NetworkType networkType, NetworkProtocolType networkProtocolType, NetworkTarget networkTarget): base(
scene, networkType, networkProtocolType, networkTarget)
{
}
public abstract uint Connect(IPEndPoint remoteEndPoint, Action onConnectComplete, Action onConnectFail, Action onConnectDisconnect,
int connectTimeout = 5000);
public abstract uint Connect(IPEndPoint remoteEndPoint, Action onConnectComplete, Action onConnectFail, int connectTimeout = 5000);
public override void Dispose()
{
ChannelId = 0;

View File

@@ -1,6 +1,7 @@
using System;
using System.IO;
using TEngine.Core;
// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract
#pragma warning disable CS8625
#pragma warning disable CS8618
@@ -26,7 +27,6 @@ namespace TEngine.Core.Network
public ANetworkMessageScheduler NetworkMessageScheduler { get; protected set; }
protected readonly Func<uint, long, long, MemoryStream, object, MemoryStream> Pack;
private readonly LastMessageInfo _lastMessageInfo = new LastMessageInfo();
protected ANetwork(Scene scene, NetworkType networkType, NetworkProtocolType networkProtocolType, NetworkTarget networkTarget)
{
@@ -69,22 +69,9 @@ namespace TEngine.Core.Network
return null;
}
#endif
if (memoryStream != null)
{
return InnerPacketParser.Pack(rpcId, routeId, memoryStream);
}
// 只针对服务器做缓存消息优化(例如群发消息等)、避免多次序列化
if (ReferenceEquals(_lastMessageInfo.Message, message))
{
_lastMessageInfo.MemoryStream.Seek(0, SeekOrigin.Begin);
return _lastMessageInfo.MemoryStream;
}
memoryStream = InnerPacketParser.Pack(rpcId, routeId, message);
_lastMessageInfo.MemoryStream = memoryStream;
_lastMessageInfo.Message = message;
return memoryStream;
return memoryStream == null
? InnerPacketParser.Pack(rpcId, routeId, message)
: InnerPacketParser.Pack(rpcId, routeId, memoryStream);
}
#endif
private MemoryStream OuterPack(uint rpcId, long routeTypeOpCode, long routeId, MemoryStream memoryStream, object message)
@@ -96,26 +83,9 @@ namespace TEngine.Core.Network
return null;
}
#endif
if (memoryStream != null)
{
return OuterPacketParser.Pack(rpcId, routeTypeOpCode, memoryStream);
}
// 只针对服务器做缓存消息优化(例如群发消息等)、避免多次序列化
// 客户端没有群发消息的功能、一般客户端都是自己缓存消息、如果这里做了缓存反而不好了
#if TENGINE_NET
if (ReferenceEquals(_lastMessageInfo.Message, message))
{
_lastMessageInfo.MemoryStream.Seek(0, SeekOrigin.Begin);
return _lastMessageInfo.MemoryStream;
}
#endif
memoryStream = OuterPacketParser.Pack(rpcId, routeTypeOpCode, message);
#if TENGINE_NET
_lastMessageInfo.MemoryStream = memoryStream;
_lastMessageInfo.Message = message;
#endif
return memoryStream;
return memoryStream == null
? OuterPacketParser.Pack(rpcId, routeTypeOpCode, message)
: OuterPacketParser.Pack(rpcId, routeTypeOpCode, memoryStream);
}
public abstract void Send(uint channelId, uint rpcId, long routeTypeOpCode, long routeId, object message);
@@ -132,8 +102,6 @@ namespace TEngine.Core.Network
NetworkType = NetworkType.None;
NetworkTarget = NetworkTarget.None;
NetworkProtocolType = NetworkProtocolType.None;
_lastMessageInfo.Dispose();
}
}
}

View File

@@ -1,19 +0,0 @@
using System;
using System.IO;
#pragma warning disable CS8625
#pragma warning disable CS8618
namespace TEngine.Core.Network
{
public class LastMessageInfo : IDisposable
{
public object Message;
public MemoryStream MemoryStream;
public void Dispose()
{
Message = null;
MemoryStream = null;
}
}
}

View File

@@ -84,7 +84,7 @@ namespace TEngine
clientNetworkComponent.Connect(ipEndPoint,null, () =>
{
Log.Error($"Unable to connect to the target server sourceServerId:{Id} targetServerId:{targetServerId}");
});
},null);
_sessions.Add(targetServerId, new ConnectInfo(clientNetworkComponent.Session, clientNetworkComponent));
return clientNetworkComponent.Session;
}

View File

@@ -9,6 +9,7 @@ namespace TEngine.Core.Network
{
private AClientNetwork Network { get; set; }
public Session Session { get; private set; }
private Action _onConnectDisconnect;
public void Initialize(NetworkProtocolType networkProtocolType, NetworkTarget networkTarget)
{
@@ -31,14 +32,15 @@ namespace TEngine.Core.Network
}
}
public void Connect(IPEndPoint remoteEndPoint, Action onConnectComplete, Action onConnectFail, int connectTimeout = 5000)
public void Connect(IPEndPoint remoteEndPoint, Action onConnectComplete, Action onConnectFail,Action onConnectDisconnect, int connectTimeout = 5000)
{
if (Network == null || Network.IsDisposed)
{
throw new NotSupportedException("Network is null or isDisposed");
}
Network.Connect(remoteEndPoint, onConnectComplete, onConnectFail, connectTimeout);
_onConnectDisconnect = onConnectDisconnect;
Network.Connect(remoteEndPoint, onConnectComplete, onConnectFail, onConnectDisconnect, connectTimeout);
Session = Session.Create(Network);
}
@@ -51,6 +53,7 @@ namespace TEngine.Core.Network
}
Session = null;
_onConnectDisconnect?.Invoke();
base.Dispose();
}
}

View File

@@ -19,7 +19,7 @@ namespace TEngine.Core.Network
private static readonly Dictionary<long, Session> Sessions = new ();
public readonly Dictionary<long, FTask<IResponse>> RequestCallback = new();
public static void Create(ANetworkMessageScheduler networkMessageScheduler, ANetworkChannel channel)
public static void Create(ANetworkMessageScheduler networkMessageScheduler, ANetworkChannel channel, NetworkTarget networkTarget)
{
#if TENGINE_DEVELOP
if (ThreadSynchronizationContext.Main.ThreadId != Thread.CurrentThread.ManagedThreadId)
@@ -33,6 +33,14 @@ namespace TEngine.Core.Network
session.NetworkMessageScheduler = networkMessageScheduler;
channel.OnDispose += session.Dispose;
channel.OnReceiveMemoryStream += session.OnReceive;
#if TENGINE_NET
if (networkTarget == NetworkTarget.Outer)
{
var interval = Define.SessionIdleCheckerInterval;
var timeOut = Define.SessionIdleCheckerTimeout;
session.AddComponent<SessionIdleCheckerComponent>().Start(interval, timeOut);
}
#endif
Sessions.Add(session.Id, session);
}

View File

@@ -37,6 +37,7 @@ namespace TEngine.Core.Network
switch (packInfo.ProtocolCode)
{
case Opcode.PingResponse:
case >= Opcode.OuterRouteMessage:
{
await Handler(session, messageType, packInfo);

View File

@@ -37,7 +37,7 @@ namespace TEngine
[ProtoIgnore] public PingResponse ResponseType { get; set; }
[ProtoMember(90)] public long RpcId { get; set; }
}
[ProtoContract]
public class PingResponse : AProto, IResponse
{
public uint OpCode()

View File

@@ -17,6 +17,7 @@ namespace TEngine.Core.Network
{
throw new NotSupportedException($"Received unsupported message protocolCode:{packInfo.ProtocolCode} messageType:{messageType}");
}
case Opcode.PingResponse:
case > Opcode.OuterRouteResponse:
{
// 这个一般是客户端Session.Call发送时使用的、目前这个逻辑只有Unity客户端时使用

View File

@@ -19,10 +19,11 @@ namespace TEngine.Core.Network
#region 线
private bool _isInit;
private Action _onConnectFail;
private Action _onConnectComplete;
private long _connectTimeoutId;
public override event Action OnDispose;
public override event Action OnConnectFail;
public override event Action OnConnectComplete;
public override event Action OnConnectDisconnect;
public override event Action<uint> OnChangeChannelId;
public override event Action<APackInfo> OnReceiveMemoryStream;
@@ -50,6 +51,11 @@ namespace TEngine.Core.Network
if (_socket.Connected)
{
if (OnConnectDisconnect != null)
{
ThreadSynchronizationContext.Main.Post(OnConnectDisconnect);
}
_socket.Disconnect(false);
_socket.Close();
}
@@ -58,7 +64,6 @@ namespace TEngine.Core.Network
_updateMinTime = 0;
_sendAction = null;
_onConnectFail = null;
_rawSendBuffer = null;
_rawReceiveBuffer = null;
@@ -89,7 +94,7 @@ namespace TEngine.Core.Network
});
}
public override uint Connect(IPEndPoint remoteEndPoint, Action onConnectComplete, Action onConnectFail, int connectTimeout = 5000)
public override uint Connect(IPEndPoint remoteEndPoint, Action onConnectComplete, Action onConnectFail, Action onConnectDisconnect, int connectTimeout = 5000)
{
if (_isInit)
{
@@ -97,8 +102,9 @@ namespace TEngine.Core.Network
}
_isInit = true;
_onConnectFail = onConnectFail;
_onConnectComplete = onConnectComplete;
OnConnectFail = onConnectFail;
OnConnectComplete = onConnectComplete;
OnConnectDisconnect = onConnectDisconnect;
ChannelId = CreateChannelId();
_kcpSettings = KCPSettings.Create(NetworkTarget);
_maxSndWnd = _kcpSettings.MaxSendWindowSize;
@@ -119,11 +125,11 @@ namespace TEngine.Core.Network
_connectTimeoutId = TimerScheduler.Instance.Core.OnceTimer(connectTimeout, () =>
{
if (_onConnectFail == null)
if (OnConnectFail == null)
{
return;
}
_onConnectFail();
OnConnectFail();
Dispose();
});
@@ -247,7 +253,7 @@ namespace TEngine.Core.Network
ThreadSynchronizationContext.Main.Post(() =>
{
OnChangeChannelId(ChannelId);
_onConnectComplete?.Invoke();
OnConnectComplete?.Invoke();
});
// 到这里正确创建上连接了、可以正常发送消息了
break;

View File

@@ -170,7 +170,6 @@ namespace TEngine.Core.Network
try
{
var receiveLength = _socket.ReceiveFrom(_rawReceiveBuffer, ref _clientEndPoint);
// Log.Debug($"_socket.ReceiveFrom receiveLength:{receiveLength}");
if (receiveLength < 1)
{
continue;
@@ -223,7 +222,6 @@ namespace TEngine.Core.Network
}
case KcpHeader.ConfirmConnection:
{
// Log.Debug("KcpHeader.ConfirmConnection");
if (receiveLength != 5)
{
break;

View File

@@ -97,7 +97,7 @@ namespace TEngine.Core.Network
return;
}
Session.Create(networkMessageScheduler, this);
Session.Create(networkMessageScheduler, this, networkTarget);
});
}

View File

@@ -18,10 +18,11 @@ namespace TEngine.Core.Network
#region 线
private bool _isInit;
private Action _onConnectFail;
private Action _onConnectComplete;
private long _connectTimeoutId;
public override event Action OnDispose;
public override event Action OnConnectFail;
public override event Action OnConnectComplete;
public override event Action OnConnectDisconnect;
public override event Action<uint> OnChangeChannelId = channelId => { };
public override event Action<APackInfo> OnReceiveMemoryStream;
@@ -30,7 +31,7 @@ namespace TEngine.Core.Network
NetworkThread.Instance.AddNetwork(this);
}
public override uint Connect(IPEndPoint remoteEndPoint, Action onConnectComplete, Action onConnectFail, int connectTimeout = 5000)
public override uint Connect(IPEndPoint remoteEndPoint, Action onConnectComplete, Action onConnectFail,Action onConnectDisconnect,int connectTimeout = 5000)
{
if (_isInit)
{
@@ -38,8 +39,8 @@ namespace TEngine.Core.Network
}
_isInit = true;
_onConnectFail = onConnectFail;
_onConnectComplete = onConnectComplete;
OnConnectFail = onConnectFail;
OnConnectComplete = onConnectComplete;
ChannelId = 0xC0000000 | (uint) new Random().Next();
_sendAction = (rpcId, routeTypeOpCode, routeId, memoryStream, message) =>
@@ -66,7 +67,7 @@ namespace TEngine.Core.Network
_connectTimeoutId = TimerScheduler.Instance.Core.OnceTimer(connectTimeout, () =>
{
_onConnectFail?.Invoke();
OnConnectFail?.Invoke();
Dispose();
});
@@ -87,7 +88,7 @@ namespace TEngine.Core.Network
return;
}
OnConnectComplete(outArgs);
OnNetworkConnectComplete(outArgs);
});
return ChannelId;
@@ -106,6 +107,10 @@ namespace TEngine.Core.Network
{
if (_socket.Connected)
{
if (OnConnectDisconnect != null)
{
ThreadSynchronizationContext.Main.Post(OnConnectDisconnect);
}
_socket.Disconnect(true);
_socket.Close();
}
@@ -145,7 +150,7 @@ namespace TEngine.Core.Network
private readonly SocketAsyncEventArgs _innArgs = new SocketAsyncEventArgs();
private Queue<MessageCacheInfo> _messageCache = new Queue<MessageCacheInfo>();
private void OnConnectComplete(SocketAsyncEventArgs asyncEventArgs)
private void OnNetworkConnectComplete(SocketAsyncEventArgs asyncEventArgs)
{
#if TENGINE_DEVELOP
if (NetworkThread.Instance.ManagedThreadId != Thread.CurrentThread.ManagedThreadId)
@@ -163,9 +168,9 @@ namespace TEngine.Core.Network
{
Log.Error($"Unable to connect to the target server asyncEventArgs:{asyncEventArgs.SocketError}");
if (_onConnectFail != null)
if (OnConnectFail != null)
{
ThreadSynchronizationContext.Main.Post(_onConnectFail);
ThreadSynchronizationContext.Main.Post(OnConnectFail);
}
Dispose();
@@ -199,9 +204,9 @@ namespace TEngine.Core.Network
_messageCache.Clear();
_messageCache = null;
if (_onConnectComplete != null)
if (OnConnectComplete != null)
{
ThreadSynchronizationContext.Main.Post(_onConnectComplete);
ThreadSynchronizationContext.Main.Post(OnConnectComplete);
}
}
@@ -509,7 +514,7 @@ namespace TEngine.Core.Network
{
case SocketAsyncOperation.Connect:
{
NetworkThread.Instance.SynchronizationContext.Post(() => OnConnectComplete(asyncEventArgs));
NetworkThread.Instance.SynchronizationContext.Post(() => OnNetworkConnectComplete(asyncEventArgs));
break;
}
case SocketAsyncOperation.Receive:

View File

@@ -173,7 +173,7 @@ namespace TEngine.Core.Network
return;
}
Session.Create(NetworkMessageScheduler, channel);
Session.Create(NetworkMessageScheduler, channel, this.NetworkTarget);
});
_connectionChannel.Add(channelId, channel);

View File

@@ -141,6 +141,10 @@ namespace TEngine.Core.Network
}
#endif
packInfo = OuterPackInfo.Create();
if (packInfo == null)
{
return null;
}
packInfo.ProtocolCode = BitConverter.ToUInt32(_messageHead, Packet.PacketLength);
packInfo.RpcId = BitConverter.ToUInt32(_messageHead, Packet.OuterPacketRpcIdLocation);
packInfo.RouteTypeCode = BitConverter.ToUInt16(_messageHead, Packet.OuterPacketRouteTypeOpCodeLocation);

View File

@@ -0,0 +1,81 @@
#if TENGINE_NET
using Microsoft.Extensions.Configuration;
#pragma warning disable CS8604
#pragma warning disable CS8601
#pragma warning disable CS8618
namespace TEngine.Core;
public static class TEngineSettingsHelper
{
public static void Initialize()
{
const string settingsName = "TEngineSettings.json";
var currentDirectory = Directory.GetCurrentDirectory();
if (!File.Exists(Path.Combine(currentDirectory, settingsName)))
{
throw new FileNotFoundException($"not found {settingsName} in OutputDirectory");
}
var configurationRoot = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile(settingsName).Build();
// 加载网络配置
LoadNetworkConfig(configurationRoot);
// 加载ProtoBuf配置
LoadProtoConfig(configurationRoot);
// 加载Excel配置
LoadExcelConfig(configurationRoot);
}
private static void LoadNetworkConfig(IConfigurationRoot root)
{
Define.SessionIdleCheckerInterval = Convert.ToInt32(root["Network:SessionIdleCheckerInterval:Value"]);
Define.SessionIdleCheckerTimeout = Convert.ToInt32(root["Network:SessionIdleCheckerTimeout:Value"]);
}
private static void LoadProtoConfig(IConfigurationRoot root)
{
// ProtoBuf文件所在的位置文件夹位置
Define.ProtoBufDirectory = root["Export:ProtoBufDirectory:Value"].GetFullPath();
// ProtoBuf生成到服务端的文件夹位置
Define.ProtoBufServerDirectory = root["Export:ProtoBufServerDirectory:Value"].GetFullPath();
// ProtoBuf生成到客户端的文件夹位置
Define.ProtoBufClientDirectory = root["Export:ProtoBufClientDirectory:Value"].GetFullPath();
// ProtoBuf生成代码模板的位置
Define.ProtoBufTemplatePath = root["Export:ProtoBufTemplatePath:Value"].GetFullPath();
}
private static void LoadExcelConfig(IConfigurationRoot root)
{
// Excel配置文件根目录
Define.ExcelProgramPath = root["Export:ExcelProgramPath:Value"].GetFullPath();
// Excel版本文件的位置
Define.ExcelVersionFile = root["Export:ExcelVersionFile:Value"].GetFullPath();
// Excel生成服务器代码的文件夹位置
Define.ExcelServerFileDirectory = root["Export:ExcelServerFileDirectory:Value"].GetFullPath();
// Excel生成客户端代码文件夹位置
Define.ExcelClientFileDirectory = root["Export:ExcelClientFileDirectory:Value"].GetFullPath();
// Excel生成服务器二进制数据文件夹位置
Define.ExcelServerBinaryDirectory = root["Export:ExcelServerBinaryDirectory:Value"].GetFullPath();
// Excel生成客户端二进制数据文件夹位置
Define.ExcelClientBinaryDirectory = root["Export:ExcelClientBinaryDirectory:Value"].GetFullPath();
// Excel生成服务器Json数据文件夹位置
Define.ExcelServerJsonDirectory = root["Export:ExcelServerJsonDirectory:Value"].GetFullPath();
// Excel生成客户端Json数据文件夹位置
Define.ExcelClientJsonDirectory = root["Export:ExcelClientJsonDirectory:Value"].GetFullPath();
// Excel生成代码模板的位置
Define.ExcelTemplatePath = root["Export:ExcelTemplatePath:Value"].GetFullPath();
// 服务器自定义导出代码文件夹位置
Define.ServerCustomExportDirectory = root["Export:ServerCustomExportDirectory:Value"].GetFullPath();
// 客户端自定义导出代码
Define.ClientCustomExportDirectory = root["Export:ClientCustomExportDirectory:Value"].GetFullPath();
// 自定义导出代码存放的程序集
Define.CustomExportAssembly = root["Export:CustomExportAssembly:Value"].GetFullPath();
}
private static string GetFullPath(this string relativePath)
{
return Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory(), relativePath));
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4070f130fd645b9459fe147291285436
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -79,7 +79,7 @@ namespace GameLogic
if (Scene.Session == null || Scene.Session.IsDisposed)
{
Scene.CreateSession(address, ProtocolType, OnConnectComplete, OnConnectFail);
Scene.CreateSession(address, ProtocolType, OnConnectComplete, OnConnectFail, OnConnectDisconnect);
}
}
@@ -95,6 +95,12 @@ namespace GameLogic
Log.Warning("Could not connect to server");
}
private void OnConnectDisconnect()
{
Status = GameClientStatus.StatusClose;
Log.Warning("OnConnectDisconnect server");
}
public virtual void Send(object message, uint rpcId = 0, long routeId = 0)
{
if (Scene.Session == null)

View File

@@ -2,6 +2,7 @@ using System;
using System.Collections;
using TEngine.Core.Network;
using TEngine.Core;
using TEngine.Logic;
using UnityEngine;
using UnityEngine.UI;
@@ -62,7 +63,7 @@ namespace TEngine.Demo
// onConnectComplete:当跟服务器建立连接后的回调
// onConnectFail:当网络无法连接或出错时的回调
// connectTimeout:连接超时时间、默认是5000毫秒
Scene.CreateSession("127.0.0.1:20000", NetworkProtocolType.KCP, OnConnectComplete, OnConnectFail);
Scene.CreateSession("127.0.0.1:20000", NetworkProtocolType.KCP, OnConnectComplete, OnConnectFail, OnConnectDisconnect);
// 注意:框架使用的ProtoBuf协议、文件定义的位置在Demo下Config/ProtoBuf/里
// 生成协议是在服务器工程生成
// ProtoBuf有三个文件:
@@ -74,6 +75,7 @@ namespace TEngine.Demo
private void OnConnectComplete()
{
IsConnect = true;
Scene.Session.AddComponent<SessionHeartbeatComponent>().Start(15);
LogDebug("已连接到服务器");
}
@@ -82,6 +84,12 @@ namespace TEngine.Demo
IsConnect = false;
LogError("无法连接到服务器");
}
private void OnConnectDisconnect()
{
IsConnect = false;
LogError("服务器主动断开了连接");
}
private void OnSendButtonClick()
{

View File

@@ -59,6 +59,20 @@
"ClientCustomExportDirectory": {
"Value": "../../Client/Unity/Assets/Scripts/Hotfix/Generate/CustomExport/",
"Comment": "客户端自定义导出代码文件夹位置"
},
"CustomExportAssembly": {
"Value": "Logic",
"Comment": "自定义导出代码存放的程序集"
}
},
"Network": {
"SessionIdleCheckerInterval": {
"Value": 10000,
"Comment": "每隔多久检查一个Session的对话时间"
},
"SessionIdleCheckerTimeout": {
"Value": 30000,
"Comment": "距上一次接收对话的时间如果超过设定的时间会自定断开Session"
}
}
}