using DaJiaoYan.Utils; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.IO; using System.Net; using System.Text; using System.Threading.Tasks; using System.Web; namespace DaJiaoYan.Services { public class HttpHandler { public readonly AsyncHttpServer HttpServer; public readonly string path; private ResponseData DefaultResponse = new ResponseData { Code = 405 }; public HttpHandler(AsyncHttpServer httpServer, string path = null) { HttpServer = httpServer; this.path = path; } public virtual void Get(HttpListenerRequest request, HttpListenerResponse response) { //StaticFile(request, ref response, (HttpListenerRequest req, HttpListenerResponse rep) => //{ // Json(ref rep, ref DefaultResponse); //}); Json(ref response, ref DefaultResponse); } public virtual void Post(HttpListenerRequest request, HttpListenerResponse response) { Json(ref response, ref DefaultResponse); } public virtual void Patch(HttpListenerRequest request, HttpListenerResponse response) { Json(ref response, ref DefaultResponse); } public virtual void Put(HttpListenerRequest request, HttpListenerResponse response) { Json(ref response, ref DefaultResponse); } public virtual void Delete(HttpListenerRequest request, HttpListenerResponse response) { Json(ref response, ref DefaultResponse); } /// /// 输出数据 /// /// /// public virtual void Response(ref HttpListenerResponse response, ref byte[] bytes) { if (bytes != null) { using (var stream = response.OutputStream) { ///获取数据,要返回给接口的 try { stream.Write(bytes, 0, bytes.Length); } catch { } } } response.Close(); } /// /// 响应Json格式数据 /// /// /// public virtual void Json(ref HttpListenerResponse response, ref ResponseData result) { response.AddHeader("Content-type", "application/json");//添加响应头信息 response.AddHeader("Cache-Control", "no-cache, no-store, must-revalidate"); response.AddHeader("Pragma", "no-cache"); response.AddHeader("Expires", "0"); response.StatusCode = result.Code; //response.ContentType = "text/plain;charset=UTF-8";//告诉客户端返回的ContentType类型为纯文本格式,编码为UTF-8 response.ContentEncoding = Encoding.UTF8; //string d = YxqService.Utils.Json.Encode(result); var data = Encoding.UTF8.GetBytes(Utils.Json.Encode(result)); Response(ref response, ref data); } } /// /// 响应数据格式 /// public struct ResponseData { [JsonProperty(PropertyName = "code")] public int Code { get; set; } [JsonProperty(PropertyName = "msg")] public object Msg { get; set; } [JsonProperty(PropertyName = "errors")] public object Errors { get; set; } [JsonProperty(PropertyName = "data")] public object Data { get; set; } } public class AsyncHttpServer { private readonly HttpListener _listener; private bool _isRunning; /// /// 中间件方法 /// /// /// /// /// public delegate bool Middleware(HttpListenerRequest request, HttpListenerResponse response); /// /// 接口方法 /// /// /// public delegate void HttpHandle(HttpListenerRequest request, HttpListenerResponse response); /// /// 中间件数组 /// private readonly List MiddleWares = new List(); /// /// 路由字典 /// private readonly Dictionary Prefixes = new Dictionary(); /// /// 默认接口 /// private readonly HttpHandler DefaultHandler; public readonly string Root; public readonly int Port; public readonly string Host; public readonly string Scheme; /// /// 监听地址 /// public readonly string Listener; public AsyncHttpServer(string root, string host = "127.0.0.1", int port = 7000, string scheme = "http") { this.Root = root; DefaultHandler = new HttpHandler(this, root); this.Port = port; this.Host = host; this.Scheme = scheme; Listener = $"{scheme}://{host}:{port}/"; _listener = new HttpListener(); _listener.Prefixes.Add(Listener); Prefixes.Add("", DefaultHandler); } /// /// 注册中间件 /// /// public void RegisterMiddleware(Middleware func) { MiddleWares.Add(func); } public void RegisterPrefix(string prefix, HttpHandler handler) { Prefixes.Add(prefix, handler); } public async Task StartAsync() { _isRunning = true; _listener.Start(); Console.WriteLine($"Server started on {string.Join(", ", _listener.Prefixes)}"); try { while (_isRunning) { var context = await _listener.GetContextAsync(); _ = Task.Factory.StartNew(() => ProcessRequest(context)); } } catch (Exception ex) { Console.WriteLine($"Server error: {ex.Message}"); } } public void Stop() { _isRunning = false; _listener.Stop(); _listener.Close(); Console.WriteLine("Server stopped"); } private bool ProcessMiddlewares(HttpListenerContext context) { bool res = true; // 中间件处理 foreach (var mw in MiddleWares) { if (!mw(context.Request, context.Response)) { context.Response.Close(); res = false; break; } } return res; } private void ProcessRequest(HttpListenerContext context) { if (!ProcessMiddlewares(context)) { return; } var request = context.Request; var response = context.Response; try { Prefixes.TryGetValue(request.Url.AbsolutePath, out var r); if (r == null) { Prefixes.TryGetValue("", out r); } HttpHandle act; if (r == null) { response.StatusCode = 404; response.Close(); act = DefaultHandler.Get; } else { switch (request.HttpMethod.ToUpper()) { case "POST": act = r.Post; break; case "PUT": act = r.Put; break; case "DELETE": act = r.Delete; break; case "PATCH": act = r.Patch; break; default: act = r.Get; break; } } act?.Invoke(request, response); } catch (Exception e) { Log.WriteLine(e.ToString()); response.StatusCode = 404; } finally { //response.Close(); } } public Dictionary ParseForm(ref HttpListenerRequest request) { Dictionary res = new Dictionary(); string content; using (Stream stream = request.InputStream) using (StreamReader reader = new StreamReader(stream, Encoding.UTF8)) { content = reader.ReadToEnd(); } if (!string.IsNullOrEmpty(content)) { foreach (var arg in content.Split('&')) { var n = arg.IndexOf('='); if (n > 0) { res[arg.Substring(0, n)] = HttpUtility.UrlDecode(arg.Substring(n + 1)); } } } return res; } } }