|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|