using EC.Util.Common; using System.Net; using System.Text; namespace EC.Util.Net; public class HttpServer { public event EventHandler OnRecData; //定义一个委托类型的事件 #region public string Host { get; set; } public string port { get; set; } private string _webHomeDir = ""; private HttpListener listener; private Thread listenThread; private string directorySeparatorChar = Path.DirectorySeparatorChar.ToString(); public string ImageUploadPath { get; set; } /// /// 设置监听端口,重启服务生效 /// //public string Port //{ // get { return this.port; } // set // { // int p; // if (string.IsNullOrEmpty(value) || !int.TryParse(value, out p)) // { // throw new Exception("给http监听器赋值的端口号无效!"); // } // this.port = value; // } //} /// /// http服务根目录 /// public string WebHomeDir { get { return this._webHomeDir; } set { if (!Directory.Exists(value)) throw new Exception("http服务器设置的根目录不存在!"); this._webHomeDir = value; } } /// /// 服务器是否在运行 /// public bool IsRunning { get { return (listener == null) ? false : listener.IsListening; } } #endregion #region public HttpServer(string host, string port, string webHomeDir, string imageUploadPath) { this.Host = host; this.port = port; this._webHomeDir = webHomeDir; ImageUploadPath = imageUploadPath; listener = new HttpListener(); } public bool AddPrefixes(string uriPrefix) { string uri = "http://" + uriPrefix + ":" + this.port + "/"; if (listener.Prefixes.Contains(uri)) return false; listener.Prefixes.Add(uri); return true; } /// /// 启动服务 /// public void Start() { try { if (listener.IsListening) return; if (!string.IsNullOrEmpty(Host) && Host.Length > 0) listener.Prefixes.Add("http://" + Host + ":" + this.port + "/"); //AGV/AGVAPI/agvCallback/ else if (listener.Prefixes == null || listener.Prefixes.Count == 0) listener.Prefixes.Add("http://localhost:" + this.port + "/"); listener.Start(); listenThread = new Thread(AcceptClient); listenThread.Name = "signserver"; listenThread.Start(); Log("开启接口监听服务:" + this.port); } catch (Exception ex) { LogUnit.Error(ex.Message); } } /// /// 停止服务 /// public void Stop() { try { if (listener != null) { //listener.Close(); //listener.Abort(); listener.Stop(); } } catch (Exception ex) { LogUnit.Error(ex.Message); } } /// /// /接受客户端请求 /// private void AcceptClient() { //int maxThreadNum, portThreadNum; ////线程池 //int minThreadNum; //ThreadPool.GetMaxThreads(out maxThreadNum, out portThreadNum); //ThreadPool.GetMinThreads(out minThreadNum, out portThreadNum); //Console.WriteLine("最大线程数:{0}", maxThreadNum); //Console.WriteLine("最小空闲线程数:{0}", minThreadNum); while (listener.IsListening) { try { HttpListenerContext context = listener.GetContext(); //new Thread(HandleRequest).Start(context); ThreadPool.QueueUserWorkItem(new WaitCallback(HandleRequest), context); } catch { } } } #endregion #region HandleRequest //处理客户端请求 private void HandleRequest(object ctx) { HttpListenerContext context = ctx as HttpListenerContext; HttpListenerResponse response = context.Response; HttpListenerRequest request = context.Request; try { context.Request.Headers.Add("Access-Control-Allow-Origin", "*"); context.Response.Headers.Add("Access-Control-Allow-Origin", "*"); string rawUrl = System.Web.HttpUtility.UrlDecode(request.RawUrl); int paramStartIndex = rawUrl.IndexOf('?'); if (paramStartIndex > 0) rawUrl = rawUrl.Substring(0, paramStartIndex); else if (paramStartIndex == 0) rawUrl = ""; if (rawUrl.EndsWith("agvCallback")) { APICallBack apiCallBack = new APICallBack(); apiCallBack.reqCode = context.Request.QueryString["reqCode"]; apiCallBack.taskCode = context.Request.QueryString["taskCode"]; apiCallBack.method = context.Request.QueryString["method"]; apiCallBack.wbCode = context.Request.QueryString["wbCode"]; apiCallBack.robotCode = context.Request.QueryString["robotCode"]; //接收POST参数 2020-5-30 Stream stream = context.Request.InputStream; System.IO.StreamReader reader = new System.IO.StreamReader(stream, Encoding.UTF8); //整理应该是接收到的值 string body = reader.ReadToEnd(); //FileUnit.Log(body); //if (JsonUtil.JSONToObject(body)!=null) //{ // apiCallBack = JsonUnit.JSONToObject(body); //} response.ContentType = "text/html;charset=utf-8"; using (StreamWriter writer = new StreamWriter(response.OutputStream, Encoding.UTF8)) { OnRecData?.Invoke(this, apiCallBack); string str = Newtonsoft.Json.JsonConvert.SerializeObject(new { Code = "0", Data = "调用成功", Message = "成功", ReqCode = apiCallBack.reqCode }); writer.Write(str); } ////Response //context.Response.StatusCode = 200; //context.Response.Headers.Add("Access-Control-Allow-Origin", "*"); //context.Response.ContentType = "application/json"; //context.Response.ContentEncoding = Encoding.UTF8; //byte[] buffer = System.Text.Encoding.UTF8.GetBytes(Newtonsoft.Json.JsonConvert.SerializeObject(new { Code = "0", Data= "调用成功", Message = "成功" , ReqCode ="",})); //context.Response.ContentLength64 = buffer.Length; //var output = context.Response.OutputStream; //output.Write(buffer, 0, buffer.Length); //output.Close(); } else if (string.Compare(rawUrl, "/ImageUpload", true) == 0) { #region 上传图片 string fileName = context.Request.QueryString["name"]; string filePath = ImageUploadPath + "\\" + DateTime.Now.ToString("yyMMdd_HHmmss_ffff") + Path.GetExtension(fileName).ToLower(); using (var stream = request.InputStream) { using (var br = new BinaryReader(stream)) { WriteStreamToFile(br, filePath, request.ContentLength64); } } response.ContentType = "text/html;charset=utf-8"; using (StreamWriter writer = new StreamWriter(response.OutputStream, Encoding.UTF8)) { writer.WriteLine("接收完成!"); } #endregion } else { #region 网页请求 string InputStream = ""; using (var streamReader = new StreamReader(request.InputStream)) { InputStream = streamReader.ReadToEnd(); } string filePath = ""; if (string.IsNullOrEmpty(rawUrl) || rawUrl.Length == 0 || rawUrl == "/") filePath = WebHomeDir + directorySeparatorChar + "Index.html"; else filePath = WebHomeDir + rawUrl.Replace("/", directorySeparatorChar); if (!File.Exists(filePath)) { response.ContentLength64 = 0; response.StatusCode = 404; response.Abort(); } else { response.StatusCode = 200; string exeName = Path.GetExtension(filePath); response.ContentType = GetContentType(exeName); FileStream fileStream = new System.IO.FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read, FileShare.ReadWrite); int byteLength = (int)fileStream.Length; byte[] fileBytes = new byte[byteLength]; fileStream.Read(fileBytes, 0, byteLength); fileStream.Close(); fileStream.Dispose(); response.ContentLength64 = byteLength; response.OutputStream.Write(fileBytes, 0, byteLength); response.OutputStream.Close(); } #endregion } } catch (Exception ex) { LogUnit.Error(ex.Message); response.StatusCode = 200; response.ContentType = "text/plain"; using (StreamWriter writer = new StreamWriter(response.OutputStream, Encoding.UTF8)) { writer.WriteLine("接收完成!"); } } try { response.Close(); } catch (Exception ex) { LogUnit.Error(ex.Message); } } #endregion #region GetContentType /// /// 获取文件对应MIME类型 /// /// 文件扩展名,如.jpg /// protected string GetContentType(string fileExtention) { if (string.Compare(fileExtention, ".html", true) == 0 || string.Compare(fileExtention, ".htm", true) == 0) return "text/html;charset=utf-8"; else if (string.Compare(fileExtention, ".js", true) == 0) return "application/javascript"; else if (string.Compare(fileExtention, ".css", true) == 0) return "text/css"; else if (string.Compare(fileExtention, ".png", true) == 0) return "image/png"; else if (string.Compare(fileExtention, ".jpg", true) == 0 || string.Compare(fileExtention, ".jpeg", true) == 0) return "image/jpeg"; else if (string.Compare(fileExtention, ".gif", true) == 0) return "image/gif"; else if (string.Compare(fileExtention, ".swf", true) == 0) return "application/x-shockwave-flash"; else if (string.Compare(fileExtention, ".pdf", true) == 0) return "application/pdf"; else return "";//application/octet-stream } #endregion #region WriteStreamToFile //const int ChunkSize = 1024 * 1024; private void WriteStreamToFile(BinaryReader br, string fileName, long length) { byte[] fileContents = new byte[] { }; var bytes = new byte[length]; int i = 0; while ((i = br.Read(bytes, 0, (int)length)) != 0) { byte[] arr = new byte[fileContents.LongLength + i]; fileContents.CopyTo(arr, 0); Array.Copy(bytes, 0, arr, fileContents.Length, i); fileContents = arr; } using (var fs = new FileStream(fileName, FileMode.Create)) { using (var bw = new BinaryWriter(fs)) { bw.Write(fileContents); } } } #endregion public void Log(string msg, bool isErr = false) { //(msg, isErr); } }