geboshi_V1/LeatherProject/ServerApp/WebServer/WebService.cs

636 lines
29 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Models;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Service;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ServerApp.WebServer
{
public class WebService
{
public string dbConStr;
private HttpListener svcHttpListener;
public Action<string, string> LogEvent;
public Action<UploadDataRecords> GetReportEvent;
private void logEvent(string msg, string warn = "正常")
{
LogEvent?.Invoke(warn, msg);
}
private void getReportEvent(UploadDataRecords data)
{
GetReportEvent?.Invoke(data);
}
RecordsService service = new RecordsService();
public void start(string HttpIP, int HttpPort)
{
try
{
if (HttpPort > 0)
{
//logEvent("Web服务启动...");
this.svcHttpListener = new HttpListener();
List<string> lstIp = HttpUtil.getLocalIPList();
//logEvent($"Web服务已启动运行于端口:{Config.LocalHttpPort.ToString()}, 监听Ip:{string.Join("|", lstIp)}");
//if (!string.IsNullOrWhiteSpace(Config.LocalIp) && lstIp.FindIndex(m => m.Contains(Config.LocalIp)) >= 0)//没指定IP/指定的不对
//{
// lstIp.Clear();
// lstIp.Add(Config.LocalIp);
//}
//lstIp.Clear();
if (lstIp.Count < 1)
{
lstIp.Add(HttpIP);
lstIp.Add("127.0.0.1");
}
logEvent($"Web服务已启动运行于端口:{HttpPort.ToString()}, 监听Ip:{string.Join("|", lstIp)}");
//for (int i = 0; i < lstIp.Count; i++)
// this.svcHttpListener.Prefixes.Add("http://" + lstIp[i] + ":" + HttpPort.ToString() + "/");
this.svcHttpListener.Prefixes.Add("http://*:" + HttpPort.ToString() + "/");
//svcHttpListener.Prefixes.Add($"https://+:{HttpPort}");
this.svcHttpListener.Start();
//logEvent($"Web服务已启动运行于端口:{Config.LocalHttpPort.ToString()}, 监听Ip:{string.Join("|", lstIp)}");
//this.svcHttpListener.GetContext().Response.AppendHeader("Access-Control-Allow-Origin", "*");//后台跨域请求,通常设置为配置文件
//this.svcHttpListener.GetContext().Response.AppendHeader("Access-Control-Allow-Credentials", "true"); //后台跨域请求
this.svcHttpListener.BeginGetContext(new AsyncCallback(this.GetContextCallBack), this.svcHttpListener);
}
//------WEB Socket
//if (Config.localIp != "" && Config.localSocketPort > 0)
//{
// logEvent( "WebSocket服务启动...");
// this.wssv = new WebSocketServer(Config.localSocketPort);
// this.wssv.AddWebSocketService<Socket1>("/socket1");
// this.wssv.Start();
// logEvent( "WebSocket服务已启动。");
//}
}
catch (Exception ex)
{
logEvent("Web服务启动失败,ex=" + ex.Message, "错误");
}
}
public void stop()
{
logEvent("正在停止WEB服务...");
try
{
if (this.svcHttpListener != null && this.svcHttpListener.IsListening)
{
this.svcHttpListener.Stop();
this.svcHttpListener.Close();
this.logEvent("Web服务已停止!");
}
//if (this.svcWebSocket != null && this.svcWebSocket.IsListening)
//{
// this.svcWebSocket.Stop();
// this.svcWebSocket = null;
// this.AddTextEvent("WebSocket", "WebSocket服务已停止!");
//}
}
catch (Exception ex)
{
logEvent("Web服务停止失败,ex=" + ex.Message, "错误");
}
}
private void GetContextCallBack(IAsyncResult ar)
{
this.svcHttpListener = (ar.AsyncState as HttpListener);
HttpListenerContext httpListenerContext;
try
{
httpListenerContext = this.svcHttpListener.EndGetContext(ar);
//httpListenerContext.Response.AppendHeader("Access-Control-Allow-Origin", "*");//后台跨域请求,通常设置为配置文件
//httpListenerContext.Response.AppendHeader("Access-Control-Allow-Credentials", "true"); //后台跨域请求
//httpListenerContext.Response.AppendHeader("Access-Control-Allow-Methods", "GET,POST");
httpListenerContext.Response.AddHeader("Access-Control-Allow-Origin", "*");
httpListenerContext.Response.AddHeader("Access-Control-Allow-Headers", "*");
httpListenerContext.Response.AddHeader("Access-Control-Allow-Methods", "*");
this.svcHttpListener.BeginGetContext(new AsyncCallback(this.GetContextCallBack), this.svcHttpListener);
}
catch (Exception ex)
{
logEvent("ex:" + ex.StackTrace, "错误");
return;
}
//
string sessionId = Convert.ToInt32(DateTime.Now.ToString("mmssfff")).ToString();//.ToString("X");
string reqHttpMethod = httpListenerContext.Request.HttpMethod;
string reqUrl = httpListenerContext.Request.RawUrl;
string reqData = "";
try
{
this.logEvent($"{sessionId} / 收到请求:{reqHttpMethod} To Url:{reqUrl}");
reqData = HttpUtil.getPostData(httpListenerContext.Request);
this.logEvent($"{sessionId} / 请求数据:{reqData}");
var subUrls = reqUrl.Trim(new char[] { '/' }).Split(new char[] { '/' });
if (subUrls[0].ToLower() == "static")
{
#region
//string InputStream = ""; //上传的数据
//using (var streamReader = new StreamReader(httpListenerContext.Request.InputStream))
// InputStream = streamReader.ReadToEnd();
// string filePath = Config.appBasePath;
string filePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
foreach (var sub in subUrls)
filePath += "\\" + sub;
if (!File.Exists(filePath)) filePath = filePath + "\\index.html";
if (!File.Exists(filePath))
{
httpListenerContext.Response.ContentLength64 = 0;
httpListenerContext.Response.StatusCode = 404;
httpListenerContext.Response.Abort();
}
else
{
httpListenerContext.Response.StatusCode = 200;
string exeName = Path.GetExtension(filePath);
httpListenerContext.Response.ContentType = HttpUtil.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();
httpListenerContext.Response.ContentLength64 = byteLength;
httpListenerContext.Response.OutputStream.Write(fileBytes, 0, byteLength);
//httpListenerContext.Response.OutputStream.Close();
}
#endregion
return;
}
if (reqData == null)
throw new Exception("请求数据不可为空!");
httpListenerContext.Response.StatusCode = 200;
JObject joReqData = JObject.Parse(reqData);
string respText;
JObject result = new JObject();
string sourceSessionId;
switch (subUrls[0].ToLower())
{
case "static": //上面已处理
break;
case "test":
HttpUtil.writeToHttpContext_text(httpListenerContext.Response, "测试回应!");
break;
case "api":
switch (subUrls[1].ToLower())
{
//查询数据
case "query_table":
#region
//if (httpListenerContext.Request.HttpMethod != "POST")
// goto case "http_error";
result = getTableList(joReqData);
respText = JsonConvert.SerializeObject(result);
this.logEvent($"{sessionId} / 返回:{(respText.Length > 30 ? respText.Substring(0, 30) : respText)}");
if (!HttpUtil.writeToHttpContext_json(httpListenerContext.Response, respText))
this.logEvent($"{sessionId} / http返回时连接已断开");
#endregion
break;
//下载数据
case "get_defect_from_batch_reel"://读取缺陷文件名列表和JSON数组
#region
//if (httpListenerContext.Request.HttpMethod != "POST")
// goto case "http_error";
result = getDefectFromBatchReel(joReqData);
respText = JsonConvert.SerializeObject(result);
this.logEvent($"{sessionId} / 返回:{(respText.Length > 30 ? respText.Substring(0, 30) : respText)}");
if (!HttpUtil.writeToHttpContext_json(httpListenerContext.Response, respText))
this.logEvent($"{sessionId} / http返回时连接已断开");
#endregion
break;
default:
HttpUtil.writeToHttpContext_text(httpListenerContext.Response, "未知请求!");
break;
}
break;
case "http_error":
result.Add("code", -1);
result.Add("msg", "不支持的请求协议!");
respText = JsonConvert.SerializeObject(result);
this.logEvent($"{sessionId} / 返回:{respText}");
if (!HttpUtil.writeToHttpContext_json(httpListenerContext.Response, respText))
{
this.logEvent($"{sessionId} / http返回时连接已断开");
//this.logEvent( id + " /http连接已断开" + (string.IsNullOrWhiteSpace(callback_url) ? "无法返回结果!" : "通过回调返回" + callback_url), 1);
//if (callback_url != null && callback_url != "")
// HttpUtil.post(callback_url, respText);
}
break;
case "url_error":
result.Add("code", -2);
result.Add("msg", "URL地址错误");
respText = JsonConvert.SerializeObject(result);
this.logEvent($"{sessionId} / 返回:{respText}");
if (!HttpUtil.writeToHttpContext_json(httpListenerContext.Response, respText))
{
this.logEvent($"{sessionId} / http返回时连接已断开");
//this.logEvent( id + " /http连接已断开" + (string.IsNullOrWhiteSpace(callback_url) ? "无法返回结果!" : "通过回调返回" + callback_url), 1);
//if (callback_url != null && callback_url != "")
// HttpUtil.post(callback_url, respText);
}
break;
case "param_error":
result.Add("code", -3);
result.Add("msg", "参数错误!");
respText = JsonConvert.SerializeObject(result);
this.logEvent($"{sessionId} / 返回:{respText}");
if (!HttpUtil.writeToHttpContext_json(httpListenerContext.Response, respText))
{
this.logEvent($"{sessionId} / http返回时连接已断开");
//this.logEvent( id + " /http连接已断开" + (string.IsNullOrWhiteSpace(callback_url) ? "无法返回结果!" : "通过回调返回" + callback_url), 1);
//if (callback_url != null && callback_url != "")
// HttpUtil.post(callback_url, respText);
}
break;
default:
HttpUtil.writeToHttpContext_text(httpListenerContext.Response, "未知请求!");
break;
}
}
catch (Exception ex)
{
this.logEvent($"{sessionId} / 异常:{ex.Message}\r\n{ex.StackTrace}", "错误");
httpListenerContext.Response.StatusCode = 500;
}
finally
{
try
{
httpListenerContext.Response.OutputStream.Close();//客户端断开时会异常
}
catch { }
}
}
/// <summary>
/// 查询批号卷号数据
/// </summary>
/// <param name="req"></param>
/// <returns></returns>
private JObject getTableList(JObject req)
{
JObject res = new JObject();
try
{
string model, batch = "", reel = "", order = "";
int totalCount = 0;
if (req.ContainsKey("batch")) batch = req.Value<string>("batch");
if (req.ContainsKey("reel")) reel = req.Value<string>("reel");
var db = new SqlSugarClient(new ConnectionConfig()
{
DbType = SqlSugar.DbType.MySql,
//InitKeyType = InitKeyType.Attribute,
IsAutoCloseConnection = true,
ConnectionString = dbConStr
});
List<UploadDataRecords> datalist = db.Queryable<UploadDataRecords>()
.Includes(m => m.DefectInfoList)
.Includes(m => m.QualifiedLimitList)
.Includes(m => m.GradeLimitList)
.ToList();
List<string> list = new List<string>();
var Find = datalist.Where(d => d.BatchId == batch && d.ReelId.IndexOf(reel)>=0).ToList();
if (Find != null && Find.Count > 0)
{
totalCount = Find.Count;
foreach (var d in Find)
{
list.Add($"PH:{d.BatchId},JH:{d.ReelId},FJH:{d.PartReelId}");
}
}
res.Add("code", 200);
res.Add("data", JArray.FromObject(list));
res.Add("totalCount", totalCount);
}
catch (Exception ex)
{
res.Add("code", -9);
res.Add("data", ex.Message);
}
return res;
}
/// <summary>
/// 获取并发送数据
/// </summary>
/// <param name="req"></param>
/// <returns></returns>
private JObject getDefectFromBatchReel(JObject req)
{
int err = 0;
JObject res = new JObject();
try
{
string batch = req.Value<string>("batch");
string reel = req.Value<string>("reel");
var db = new SqlSugarClient(new ConnectionConfig()
{
DbType = SqlSugar.DbType.MySql,
//InitKeyType = InitKeyType.Attribute,
IsAutoCloseConnection = true,
ConnectionString = dbConStr
});
var data = db.Queryable<UploadDataRecords>()
.Includes(m => m.DefectInfoList)
.Includes(m => m.QualifiedLimitList)
.Includes(m => m.GradeLimitList)
.First(m => m.BatchId == batch && m.ReelId == reel);
if(data == null )
throw new Exception($"批号:{batch},卷号:{reel},数据不存在!");
err = 2;
getReportEvent(data);
string file_path = $"{Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)}\\temp.xlsx";
//--缺陷
if (!string.IsNullOrEmpty(file_path))
{
if (!File.Exists(file_path))
throw new Exception(file_path + " 缺陷文件不存在!");
res.Add("code", 200);
//res.Add("data", Convert.ToBase64String(File.ReadAllBytes(file_path)));
res.Add("data", (File.ReadAllBytes(file_path)));
}
else
throw new Exception($"文件错误file_name={file_path}");
}
catch (Exception ex)
{
res.Add("code", -9);
res.Add("data", ex.Message);
}
return res;
}
}
public static class HttpUtil
{
/// <summary>
/// 获取本机IP地址列表
/// </summary>
/// <param name="_type">Wireless80211:本地所有IP仅127.0.0.1Ethernet:仅获取以太网接口的 IP 地址</param>
public static List<string> getLocalIPList(NetworkInterfaceType _type = NetworkInterfaceType.Unknown)
{
List<string> output = new List<string>();
foreach (NetworkInterface item in NetworkInterface.GetAllNetworkInterfaces())
{
if ((_type == NetworkInterfaceType.Unknown || item.NetworkInterfaceType == _type) && item.OperationalStatus == OperationalStatus.Up)
{
foreach (UnicastIPAddressInformation ip in item.GetIPProperties().UnicastAddresses)
{
if (ip.Address.AddressFamily == AddressFamily.InterNetwork)
{
//API.OutputDebugString($"{item.NetworkInterfaceType.ToString()}; {ip.Address.AddressFamily.ToString()}; {ip.Address.ToString()}");
output.Add(ip.Address.ToString());
}
}
}
}
return output;
}
//读取请求数据
public static string getPostData(HttpListenerRequest request)
{
if (!request.HasEntityBody)
return null;
string result;
using (Stream inputStream = request.InputStream)
{
using (StreamReader streamReader = new StreamReader(inputStream, Encoding.UTF8))
result = streamReader.ReadToEnd();
}
return result;
}
/// <summary>
/// POST请求接口调用
/// </summary>
/// <param name="url"></param>
/// <param name="json"></param>
/// <returns></returns>
public static void post(string url, string json, Action<JObject> callBack = null)
{
System.Threading.ThreadPool.QueueUserWorkItem(
new WaitCallback(o =>
{
var data = (JObject)o;
if (callBack == null)
postSync(data["url"].ToString(), data["json"].ToString(), false);
else
callBack(postSync(data["url"].ToString(), data["json"].ToString()));
}),
JObject.FromObject(new { url, json })
);
}
//HttpWebRequest方式
public static JObject postSync2(string url, string json, bool recvResp = true)
{
JObject resp = new JObject();
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
//request.ContentType = "application/x-www-form-urlencoded";
request.ContentType = "application /json";
StreamWriter requestWriter = new StreamWriter(request.GetRequestStream(), System.Text.Encoding.UTF8);
requestWriter.Write(json);
requestWriter.Flush();
requestWriter.Close();
if (recvResp)
{
WebResponse webResponse = request.GetResponse();
Stream webStream = webResponse.GetResponseStream();
StreamReader responseReader = new StreamReader(webStream);
resp.Add("data", responseReader.ReadToEnd());
resp.Add("success", true);
}
else
{
request.GetResponse().Close();//必需调用此GetResponse后上面的write才会发送出去
resp.Add("data", "");
resp.Add("success", true);
}
}
catch (Exception ex)
{
resp.Add("success", false);
resp.Add("data", ex.Message);
}
return resp;
}
//HttpClient方式
public static JObject postSync(string url, string json, bool recvResp = true, bool isJson = false)
{
JObject resp = new JObject();
try
{
HttpClient http = new HttpClient();
StringContent dataContent;
//第一种方式data是json格式
if (isJson)
dataContent = new StringContent(json, System.Text.Encoding.UTF8, "application/json"); // {"PageNum":"1","PageSIze":"20","info":"311011500300661"}
else
{
// 第二种方式form表单提交 内容post 提交都在StringContent请求body中添加
string lsUrlEncodeStr = json2Params(JObject.Parse(json));
dataContent = new StringContent(lsUrlEncodeStr, System.Text.Encoding.UTF8, "application/x-www-form-urlencoded"); //PageNum=1&PageSize=20&info=311011500300661
}
http.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", "token");
var taskstr = http.PostAsync(url, dataContent).Result.Content.ReadAsStringAsync();
//API.OutputDebugString("wlq postSync:url=" + url + ";resp=" + taskstr.Result);
//读取返回数据
//return taskstr.Result;
if (recvResp)
{
resp.Add("data", taskstr.Result);
resp.Add("success", true);
}
else
{
resp.Add("data", "");
resp.Add("success", true);
}
}
catch (Exception ex)
{
resp.Add("success", false);
resp.Add("data", ex.Message);
}
return resp;
}
/// <summary>
/// 向HTTP连接写入数据
/// </summary>
/// <param name="resp">HttpListenerContext.Response</param>
/// <param name="data"></param>
/// <returns>如果连接关闭返回 false</returns>
public static bool writeToHttpContext(HttpListenerResponse resp, byte[] dataBuff)
{
try
{
resp.OutputStream.Write(dataBuff, 0, dataBuff.Length);
resp.OutputStream.Flush();
return true;
}
catch (Exception ex)
{
return false;
}
}
public static bool writeToHttpContext_json(HttpListenerResponse resp, string json)
{
byte[] buff = Encoding.UTF8.GetBytes(json);
resp.ContentType = "application/json";
resp.ContentEncoding = Encoding.UTF8;
return writeToHttpContext(resp, buff);
}
public static bool writeToHttpContext_text(HttpListenerResponse resp, string text)
{
byte[] buff = Encoding.UTF8.GetBytes(text);
resp.ContentType = "application/text";
resp.ContentEncoding = Encoding.UTF8;
return writeToHttpContext(resp, buff);
}
private static string json2Params(JObject json)
{
string result = "";
IEnumerable<JProperty> properties = json.Properties();
foreach (JProperty item in properties)
{
result += item.Name.ToString() + "=" + item.Value.ToString() + "&";
// item.Name 为 键
// item.Value 为 值
}
result = result.Substring(0, result.Length - 1);
//string result1 = WebUtility.UrlEncode(result);//转义字符大写
////string result2 = HttpUtility.UrlEncode(result);//转义字符小写
return result;
}
/// <summary>
/// 获取文件对应MIME类型
/// </summary>
/// <param name="fileExtention">文件扩展名,如.jpg</param>
/// <returns></returns>
public static 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, ".bcmap", true) == 0)
return "image/svg+xml";
else if (string.Compare(fileExtention, ".properties", true) == 0)
return "application/octet-stream";
else if (string.Compare(fileExtention, ".map", true) == 0)
return "text/plain";
else if (string.Compare(fileExtention, ".svg", true) == 0)
return "image/svg+xml";
else if (string.Compare(fileExtention, ".pdf", true) == 0)
return "application/pdf";
else if (string.Compare(fileExtention, ".txt", true) == 0)
return "text/*";
else if (string.Compare(fileExtention, ".dat", true) == 0)
return "text/*";
else
return "application/octet-stream";//application/octet-stream
}
}
}