You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

358 lines
12 KiB

using EC.Util.Common;
using System.Net;
using System.Text;
namespace EC.Util.Net;
public class HttpServer
{
public event EventHandler<APICallBack> 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; }
/// <summary>
/// 设置监听端口,重启服务生效
/// </summary>
//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;
// }
//}
/// <summary>
/// http服务根目录
/// </summary>
public string WebHomeDir
{
get { return this._webHomeDir; }
set
{
if (!Directory.Exists(value))
throw new Exception("http服务器设置的根目录不存在!");
this._webHomeDir = value;
}
}
/// <summary>
/// 服务器是否在运行
/// </summary>
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;
}
/// <summary>
/// 启动服务
/// </summary>
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);
}
}
/// <summary>
/// 停止服务
/// </summary>
public void Stop()
{
try
{
if (listener != null)
{
//listener.Close();
//listener.Abort();
listener.Stop();
}
}
catch (Exception ex)
{
LogUnit.Error(ex.Message);
}
}
/// <summary>
/// /接受客户端请求
/// </summary>
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<APICallBack>(body)!=null)
//{
// apiCallBack = JsonUnit.JSONToObject<APICallBack>(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
/// <summary>
/// 获取文件对应MIME类型
/// </summary>
/// <param name="fileExtention">文件扩展名,如.jpg</param>
/// <returns></returns>
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);
}
}