Windows服务项目
Grass.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http.Headers;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;
using System.Xml.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace Grass
{
public class GrassRoot
{
private HttpListener listener;
private string url = "http://+:8422/"; //"http://localhost:8422/" 监听的URL//listener.Prefixes.Add("http://+:8422/"); // 监听所有IP地址上的8422端口")
private string proxy_url = string.Empty;
volatile bool runing = false;
private Thread listenThread;
private List<Thread> ListThread = new List<Thread>();
private readonly SynchronizationContext _synchronizationContext = SynchronizationContext.Current;//跨线程需要同步上下文
public GrassRoot()
{
listener = new HttpListener();
listener.Prefixes.Add(url);
listener.Start();
}
public void Start()
{
if (listener == null)
{
listener = new HttpListener();
}
if (listener.IsListening == false)
{
listener.Start();
}
if (this.listenThread == null || this.listenThread.IsAlive == false)
{
this.listenThread = new Thread(new ThreadStart(ListenForRequests));
this.listenThread.IsBackground = false;//前台线程不会自动退出,thread类默认前台线程,前台线程会阻塞主线程
}
switch (listenThread.ThreadState)
{
case System.Threading.ThreadState.Unstarted:
this.listenThread.Start();
runing = true;
break;
case System.Threading.ThreadState.StopRequested:
case System.Threading.ThreadState.AbortRequested:
case System.Threading.ThreadState.Aborted:
case System.Threading.ThreadState.Stopped:
case System.Threading.ThreadState.Suspended:
case System.Threading.ThreadState.SuspendRequested:
this.listenThread.Abort();
this.listenThread = new Thread(new ThreadStart(ListenForRequests));
this.listenThread.IsBackground = false;//前台线程不会自动退出,thread类默认前台线程,前台线程会阻塞主线程
this.listenThread.Start();
runing = true;
break;
case System.Threading.ThreadState.Running:
runing = true;
break;
}
}
public void Stop()
{
if (listener != null && listener.IsListening == true)
{
listener.Stop();
listener.Close();
}
ListThread.Clear();
GC.Collect();
}
private void ListenForRequests()
{
Task.Run(() =>
{
// 创建一个新的线程来处理客户端通信
Thread clientThread = new Thread(HandleRequests);
clientThread.IsBackground = true; //后台线程不阻塞主线程,后台线程用完后自动退出
clientThread.Start();
ListThread.Add(clientThread);
//剔除睡眠线程
for (int i = 0; i < ListThread.Count; i++)
{
if (ListThread.ElementAt<Thread>(i).ThreadState == System.Threading.ThreadState.Stopped)
ListThread.RemoveAt(i);
}
GC.Collect();
});
}
// 处理请求
private async void HandleRequests()
{
while (listener.IsListening)
{
// 等待传入的请求
HttpListenerContext context = await listener.GetContextAsync();
// 处理请求
HttpListenerRequest request = context.Request;
HttpListenerResponse response = context.Response;
Console.WriteLine($"Received request for {request.Url}");
// 构造响应内容
string responseString = "<html><body><h1>Hello, World!</h1></body></html>";
byte[] buffer = Encoding.UTF8.GetBytes(responseString);
// 设置响应头
response.ContentType = "text/html";
response.ContentLength64 = buffer.Length;
response.ContentEncoding = Encoding.UTF8;
// 获取当前UTC时间并转换为本地时间
DateTime utcNow = DateTime.UtcNow;
TimeZoneInfo localZone = TimeZoneInfo.Local;
DateTime localTime = TimeZoneInfo.ConvertTimeFromUtc(utcNow, localZone);
// 设置响应头中的Date和Last-Modified为本地时间
//response.Headers["Date"] = localTime.ToString("R"); // RFC1123格式
response.Headers["Last-Modified"] = localTime.ToString("R"); // RFC1123格式
//response.Headers["Date"] = DateTime.UtcNow.ToString("R"); // RFC1123格式
//response.Headers["Last-Modified"] = DateTime.UtcNow.ToString("R"); // RFC1123格式
// 发送响应
await response.OutputStream.WriteAsync(buffer, 0, buffer.Length);
response.Close();
}
}
}
}
Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
namespace GrassRoot
{
internal static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
static void Main()
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new Service1()
};
ServiceBase.Run(ServicesToRun);
}
}
}
Service1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
using Grass;
namespace GrassRoot
{
public partial class Service1 : ServiceBase
{
Grass.GrassRoot grassRoot =new Grass.GrassRoot();
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
grassRoot.Start();
EventLog.WriteEntry("GrassRoot started");
}
protected override void OnStop()
{
grassRoot.Stop();
EventLog.WriteEntry("GrassRoot stopped");
}
}
}