| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323 |
- 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);
- }
- /// <summary>
- /// 输出数据
- /// </summary>
- /// <param name="response"></param>
- /// <param name="bytes"></param>
- 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();
- }
- /// <summary>
- /// 响应Json格式数据
- /// </summary>
- /// <param name="response"></param>
- /// <param name="result"></param>
- 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);
- }
- }
- /// <summary>
- /// 响应数据格式
- /// </summary>
- 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;
- /// <summary>
- /// 中间件方法
- /// </summary>
- /// <param name="request"></param>
- /// <param name="response"></param>
- /// <param name="result"></param>
- /// <returns></returns>
- public delegate bool Middleware(HttpListenerRequest request, HttpListenerResponse response);
- /// <summary>
- /// 接口方法
- /// </summary>
- /// <param name="request"></param>
- /// <param name="result"></param>
- public delegate void HttpHandle(HttpListenerRequest request, HttpListenerResponse response);
- /// <summary>
- /// 中间件数组
- /// </summary>
- private readonly List<Middleware> MiddleWares = new List<Middleware>();
- /// <summary>
- /// 路由字典
- /// </summary>
- private readonly Dictionary<string, HttpHandler> Prefixes = new Dictionary<string, HttpHandler>();
- /// <summary>
- /// 默认接口
- /// </summary>
- private readonly HttpHandler DefaultHandler;
- public readonly string Root;
- public readonly int Port;
- public readonly string Host;
- public readonly string Scheme;
- /// <summary>
- /// 监听地址
- /// </summary>
- 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);
- }
- /// <summary>
- /// 注册中间件
- /// </summary>
- /// <param name="func"></param>
- 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<string, string> ParseForm(ref HttpListenerRequest request)
- {
- Dictionary<string, string> res = new Dictionary<string, string>();
- 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;
- }
- }
- }
|