Преглед изворни кода

增加http组件,可以分发http请求

tanghai пре 8 година
родитељ
комит
f039f23237

+ 17 - 0
Server/Model/Base/Other/HttpHandlerAttribute.cs

@@ -0,0 +1,17 @@
+using System;
+
+namespace Model
+{
+	public class HttpHandlerAttribute : Attribute
+	{
+		public AppType AppType { get; }
+
+		public string Path { get; }
+
+		public HttpHandlerAttribute(AppType appType, string path)
+		{
+			this.AppType = appType;
+			this.Path = path;
+		}
+	}
+}

+ 9 - 0
Server/Model/Base/Other/IHttpHandler.cs

@@ -0,0 +1,9 @@
+using System.Net;
+
+namespace Model
+{
+	public interface IHttpHandler
+	{
+		void Handle(HttpListenerContext context);
+	}
+}

+ 132 - 0
Server/Model/Component/HttpComponent.cs

@@ -0,0 +1,132 @@
+using System;
+using System.Collections.Generic;
+using System.Net;
+
+namespace Model
+{
+	[ObjectEvent]
+	public class HttpComponentComponentEvent : ObjectEvent<HttpComponent>, IAwake, ILoad
+	{
+		public void Awake()
+		{
+			this.Get().Awake();
+		}
+
+		public void Load()
+		{
+			this.Get().Load();
+		}
+	}
+	
+	/// <summary>
+	/// http请求分发器
+	/// </summary>
+	public class HttpComponent : Component
+	{
+		public AppType appType;
+		public HttpListener listener;
+		public HttpConfig HttpConfig;
+		public Dictionary<string, IHttpHandler> dispatcher;
+
+		public void Awake()
+		{
+			StartConfig startConfig = Game.Scene.GetComponent<StartConfigComponent>().StartConfig;
+			this.appType = startConfig.AppType;
+			this.HttpConfig = startConfig.GetComponent<HttpConfig>();
+
+			this.Load();
+
+			try
+			{
+				this.listener = new HttpListener();
+
+				if (this.HttpConfig.Url == null)
+				{
+					this.HttpConfig.Url = "";
+				}
+				foreach (string s in this.HttpConfig.Url.Split(';'))
+				{
+					if (s.Trim() == "")
+					{
+						continue;
+					}
+					this.listener.Prefixes.Add(s);
+				}
+
+				this.listener.Start();
+
+				this.Accept();
+			}
+			catch (HttpListenerException e)
+			{
+				throw new Exception($"http server error: {e.ErrorCode}", e);
+			}
+		}
+
+		public void Load()
+		{
+			this.dispatcher = new Dictionary<string, IHttpHandler>();
+
+			Type[] types = DllHelper.GetMonoTypes();
+
+			foreach (Type type in types)
+			{
+				object[] attrs = type.GetCustomAttributes(typeof(HttpHandlerAttribute), false);
+				if (attrs.Length == 0)
+				{
+					continue;
+				}
+
+				HttpHandlerAttribute httpHandlerAttribute = (HttpHandlerAttribute)attrs[0];
+				if (!httpHandlerAttribute.AppType.Is(this.appType))
+				{
+					continue;
+				}
+
+				object obj = Activator.CreateInstance(type);
+
+				IHttpHandler ihttpHandler = obj as IHttpHandler;
+				if (ihttpHandler == null)
+				{
+					throw new Exception($"HttpHandler handler not inherit IHttpHandler class: {obj.GetType().FullName}");
+				}
+				this.dispatcher.Add(httpHandlerAttribute.Path, ihttpHandler);
+			}
+		}
+
+		public async void Accept()
+		{
+			while (true)
+			{
+				if (this.Id == 0)
+				{
+					return;
+				}
+
+				HttpListenerContext context = await this.listener.GetContextAsync();
+
+				IHttpHandler handler;
+				if (this.dispatcher.TryGetValue(context.Request.Url.AbsolutePath, out handler))
+				{
+					handler.Handle(context);
+				}
+
+				//Log.Debug($"{context.Request.Url.AbsolutePath} {context.Request.Url.AbsoluteUri} {context.Request.Url.LocalPath} {context.Request.Url.IdnHost} " +
+				//          $"{context.Request.Url.Host} {context.Request.Url.}");
+			}
+		}
+
+		public override void Dispose()
+		{
+			if (this.Id == 0)
+			{
+				return;
+			}
+
+			base.Dispose();
+
+			this.listener.Stop();
+			this.listener.Close();
+		}
+	}
+}

+ 3 - 1
Server/Model/Server.Model.csproj

@@ -136,7 +136,10 @@
     <Compile Include="..\..\Unity\Assets\Scripts\Helper\MongoHelper.cs">
       <Link>Helper\MongoHelper.cs</Link>
     </Compile>
+    <Compile Include="Base\Other\HttpHandlerAttribute.cs" />
+    <Compile Include="Base\Other\IHttpHandler.cs" />
     <Compile Include="Component\ActorProxyComponent.cs" />
+    <Compile Include="Component\HttpComponent.cs" />
     <Compile Include="Component\ServerFrameComponent.cs" />
     <Compile Include="Component\PlayerComponent.cs" />
     <Compile Include="Component\Unit\UnitGateComponent.cs" />
@@ -225,7 +228,6 @@
       <Name>Server.Base</Name>
     </ProjectReference>
   </ItemGroup>
-  <ItemGroup />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.