喜欢轻量级的朋友可以看一下。
httplistner可以像socket一样绑定端口,响应http报文。
直接上代码。
class WebServerThread
{
public delegate void AddLog(string log, bool view = true);
private static int portNO = 0;
private static AddLog _addLog;
private static Thread serverThread = null;
private static int startRes = 0;
private static HttpListener listener = new HttpListener();
internal static bool Start(AddLog onLog, int port)
{
_addLog = onLog;
portNO = port;
if (serverThread != null)
{
return false;
}
serverThread = new Thread(ThreadRun);
startRes = 0;
serverThread.Start();
while (startRes == 0)
{
Thread.Sleep(1000);
}
if (startRes < 0)
{
return false;
}
return true;
}
internal static bool ReStart(int port)
{
if (serverThread == null)
{
return false;
}
Stop();
portNO = port;
if (serverThread != null)
{
return false;
}
serverThread = new Thread(ThreadRun);
startRes = 0;
serverThread.Start();
while (startRes == 0)
{
Thread.Sleep(1000);
}
if (startRes < 0)
{
return false;
}
return true;
}
internal static bool Stop()
{
if (serverThread == null)
{
return true;
}
if (listener != null)
{
listener.Stop();
listener.Abort();
listener.Close();
listener = null;
}
serverThread.Abort();
serverThread.Join();
serverThread = null;
_addLog("WEB服务已停止!");
return true;
}
private static void ThreadRun()
{
try
{
listener.AuthenticationSchemes = AuthenticationSchemes.Anonymous;//指定身份验证 Anonymous匿名访问
listener.Prefixes.Add("http://+:" + portNO.ToString() + "/");
listener.Start();
//线程池
int minThreadNum;
int portThreadNum;
int maxThreadNum;
ThreadPool.GetMaxThreads(out maxThreadNum, out portThreadNum);
ThreadPool.GetMinThreads(out minThreadNum, out portThreadNum);
startRes = 1;
_addLog("WEB服务已启动!");
while (true)
{
//等待请求连接
//没有请求则GetContext处于阻塞状态
try
{
if (listener == null)
{
break;
}
HttpListenerContext ctx = listener.GetContext();
ThreadPool.QueueUserWorkItem(new WaitCallback(TaskProc), ctx);
}
catch
{
}
}
}
catch
{
startRes = -1;
Stop();
}
}
static void TaskProc(object o)
{
try
{
HttpListenerContext ctx = (HttpListenerContext)o;
ctx.Response.StatusCode = 200;//设置返回给客服端http状态代码
if (ctx.Request.HttpMethod == "GET")
{
//接收Get参数
//使用Writer输出http响应代码,UTF8格式
string filepath = ctx.Request.Url.AbsolutePath;
filepath = filepath.TrimStart('/');
if (filepath == "")
{
ctx.Response.ContentType = "text/html;charset=utf-8";
using (StreamWriter writer = new StreamWriter(ctx.Response.OutputStream, Encoding.UTF8))
{
string html = File.ReadAllText("dist/index.html", Encoding.UTF8);
writer.Write(html);
}
}
else
{
filepath = Uri.UnescapeDataString(filepath);
if (!filepath.StartsWith("report-mobile/") && filepath != "favicon.ico")
{
ctx.Response.ContentType = "text/html;charset=utf-8";
using (StreamWriter writer = new StreamWriter(ctx.Response.OutputStream, Encoding.UTF8))
{
string html = File.ReadAllText("dist/index.html", Encoding.UTF8);
writer.Write(html);
}
}
else
{
if (filepath.StartsWith("report-mobile/"))
{
filepath = "dist" + filepath.Substring("report-mobile".Length);
}
string ext = "";
if (filepath.Contains("."))
{
ext = filepath.Substring(filepath.LastIndexOf('.') + 1);
switch (ext.ToLower())
{
case "html":
case "htm":
ctx.Response.ContentType = "text/html;charset=utf-8";
break;
case "txt":
ctx.Response.ContentType = "text/plain";
break;
case "css":
ctx.Response.ContentType = "text/css";
break;
case "js":
ctx.Response.ContentType = "application/javascript";
break;
case "xml":
ctx.Response.ContentType = "text/xml";
break;
case "gif":
ctx.Response.ContentType = "image/gif";
break;
case "jpg":
case "jpeg":
ctx.Response.ContentType = "image/jpeg";
break;
case "png":
ctx.Response.ContentType = "image/png";
break;
case "swf":
ctx.Response.ContentType = "application/x-shockwave-flash";
break;
default:
ctx.Response.ContentType = "application/octet-stream";
break;
}
if (File.Exists(filepath))
{
byte[] fileinfo = File.ReadAllBytes(filepath);
ctx.Response.OutputStream.Write(fileinfo, 0, fileinfo.Length);
}
else
{
ctx.Response.ContentType = "text/html;charset=utf-8";
using (StreamWriter writer = new StreamWriter(ctx.Response.OutputStream, Encoding.UTF8))
{
string html = File.ReadAllText("dist/index.html", Encoding.UTF8);
writer.Write(html);
}
}
}
else
{
ctx.Response.ContentType = "text/html;charset=utf-8";
using (StreamWriter writer = new StreamWriter(ctx.Response.OutputStream, Encoding.UTF8))
{
string html = File.ReadAllText("dist/index.html", Encoding.UTF8);
writer.Write(html);
}
}
}
}
ctx.Response.Close();
}
if (ctx.Request.HttpMethod == "OPTION")
{
}
if (ctx.Request.HttpMethod == "POST")
{
//接收POST参数
string rawUrl = ctx.Request.RawUrl.TrimStart('/');
Stream stream = ctx.Request.InputStream;
if (rawUrl.TrimEnd('/') == "Upload")
{
//HttpMultipartFormParser parser = new HttpMultipartFormParser(ctx.Request, Encoding.UTF8);
//var list = parser.ParseIntoElementList();
//foreach (var aa in list)
//{
// File.WriteAllBytes("Img/" + aa.Name, aa.Data);
//}
//ctx.Response.ContentType = "text/html;charset=utf-8";
//using (StreamWriter writer = new StreamWriter(ctx.Response.OutputStream, Encoding.UTF8))
//{
// writer.WriteLine("接收完成!");
//}
//return;
}
System.IO.StreamReader reader = new System.IO.StreamReader(stream, Encoding.UTF8);
string body = reader.ReadToEnd();
var dicKeyValue = JsonConvert.DeserializeObject<Dictionary<string, object>>(body);
string logFileName = "";
string funcName = "";
string ret = "";
DateTime reciveTime = DateTime.Now;
//使用Writer输出http响应代码,UTF8格式
ctx.Response.Headers.Add("Access-Control-Allow-Origin", "*");
ctx.Response.Headers.Add("Access-Control-Allow-Methods", "POST,GET");
ctx.Response.Headers.Add("Access-Control-Max-Age", "1800");
using (StreamWriter writer = new StreamWriter(ctx.Response.OutputStream, Encoding.UTF8))
{
try
{
dicKeyValue = WebService.PostService(ctx, dicKeyValue, ref logFileName, ref funcName);
}
catch (Exception ex)
{
dicKeyValue.Clear();
dicKeyValue.Add("STATE", "-9999");
dicKeyValue.Add("ERROR_INFO", ex.Message);
}
ret = JsonConvert.SerializeObject(dicKeyValue, Formatting.None);
writer.Write(ret);
}
//if (ctx.Request.HttpMethod == "OPTIONS") {
// ctx.Response.Headers.Add("Access-Control-Allow-Methods", "GET, POST, DELETE");
// ctx.Response.Headers.Add("Access-Control-Allow-Headers", "content-type");
//}
ctx.Response.Close();
if (logFileName == "")
{
logFileName = "UnknowCode";
}
string today = DateTime.Now.ToString("yyyyMMdd");
WriteLog("Logs/" + today + "/" + logFileName + ".txt", "[RECIVE]:" + funcName + "\r\n" + body);
WriteLog("Logs/" + today + "/" + logFileName + ".txt", "[SEND]:" + funcName + "\r\n" + ret);
}
}
catch (Exception ex)
{
WriteLog("Logs/" + "error.txt", ex.Message);
}
}
static void WriteLog(string fileName, string content)
{
string filePath = "";
if (fileName.Contains("/"))
{
filePath = fileName.Substring(0, fileName.LastIndexOf("/"));
if (!Directory.Exists(filePath))
{
Directory.CreateDirectory(filePath);
}
}
while (true)
{
try
{
if (content.Length > 1000)
{
content = content.Substring(0, 1000);
}
File.AppendAllText(fileName, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ":" + content + "\r\n");
break;
}
catch
{
Thread.Sleep(100);
}
}
}