首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >WPF开发-WEB服务器

WPF开发-WEB服务器

作者头像
码客说
发布2021-10-20 16:15:13
发布2021-10-20 16:15:13
4K00
代码可运行
举报
文章被收录于专栏:码客码客
运行总次数:0
代码可运行

前言

现在我想实现客户端项目内需要集成WEB服务器,用来提供文件的展示功能,有两种方法

  • 集成第三方WEB服务器如Nginx
  • C#实现

目前我的项目已经从集成Nginx更换为了C#实现,因为需求还是比较简单的,不需要Nginx那么多功能。

集成Nginx

下载Nginx放在项目根目录:如nginx/

属性=>生成事件=>生成前事件命令行中添加

代码语言:javascript
代码运行次数:0
运行
复制
taskkill /f /t /im nginx.exe
xcopy /Y /i /e $(ProjectDir)\nginx $(TargetDir)\nginx

项目中启动

代码语言:javascript
代码运行次数:0
运行
复制
/// <summary>
/// 启动Nginx.
/// </summary>
private static void StartNginx()
{
    try
    {
        StopNginx();
        string basePath = AppDomain.CurrentDomain.BaseDirectory;
        string nginxPath = System.IO.Path.Combine(basePath, "nginx");
        string nginxTempPath = System.IO.Path.Combine(nginxPath, "temp");
        DirectoryInfo di = new DirectoryInfo(nginxTempPath);
        if (!di.Exists)
        {
            di.Create();
        }
        Process mps = new Process();
        ProcessStartInfo mpsi = new ProcessStartInfo("nginx.exe")
        {
            WorkingDirectory = nginxPath,
            UseShellExecute = true,
            RedirectStandardInput = false,
            RedirectStandardOutput = false,
            CreateNoWindow = true,
            WindowStyle = ProcessWindowStyle.Hidden
        };
        mps.StartInfo = mpsi;
        mps.Start();
    }
    catch (Exception ex)
    {
        LogHelper.WriteErrLog("【启动Nginx】(StartNginx)无法启动Nginx," + ex.Message, ex);
    }
}

/// <summary>
/// 关闭Nginx.
/// </summary>
private static void StopNginx()
{
    try
    {
        Process[] processes = Process.GetProcessesByName("nginx");
        foreach (Process p in processes)
        {
            string basePath = AppDomain.CurrentDomain.BaseDirectory;
            string nginxPath = System.IO.Path.Combine(basePath, "nginx", "nginx.exe");
            try
            {
                if (nginxPath == p.MainModule.FileName)
                {
                    p.Kill();
                    p.Close();
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteErrLog("【停止Nginx】(StartNginx)无法停止Nginx," + ex.Message, ex);
            }
        }
    }
    catch (Exception ex)
    {
        LogHelper.WriteErrLog("【停止Nginx】(StartNginx)无法和获取到系统进程," + ex.Message, ex);
    }
}

端口号和服务目录都在Nginx的配置文件中配置

C#实现

工具类(ZServerHelper)

代码语言:javascript
代码运行次数:0
运行
复制
using System;
using System.Net;

namespace SchoolClient.Utils.HttpServer
{
    public class ZServerHelper
    {
        private HttpListener httpListener = new HttpListener();
        private string basePath = "";

        public void Setup(string basePath, int port = 8080)
        {
            this.basePath = basePath;
            httpListener.AuthenticationSchemes = AuthenticationSchemes.Anonymous;
            httpListener.Prefixes.Add(string.Format("http://*:{0}/", port));
            httpListener.Start();//开启服务

            Receive();//异步接收请求
        }

        private void Receive()
        {
            httpListener.BeginGetContext(new AsyncCallback(EndReceive), null);
        }

        private void EndReceive(IAsyncResult ar)
        {
            HttpListenerContext context = httpListener.EndGetContext(ar);
            ZDispather(context);//解析请求
            Receive();
        }

        private ZRequestHelper RequestHelper;
        private ZResponseHelper ResponseHelper;

        private void ZDispather(HttpListenerContext context)
        {
            HttpListenerRequest request = context.Request;
            HttpListenerResponse response = context.Response;
            RequestHelper = new ZRequestHelper(request, basePath);
            ResponseHelper = new ZResponseHelper(response);
            RequestHelper.DispatchResources(fs =>
            {
                ResponseHelper.WriteToClient(fs);// 对相应的请求做出回应
            });
        }
    }
}

请求(ZRequestHelper)

代码语言:javascript
代码运行次数:0
运行
复制
using System;
using System.IO;
using System.Net;

namespace SchoolClient.Utils.HttpServer
{
    public class ZRequestHelper
    {
        private HttpListenerRequest request;
        private string basepath = "";

        public ZRequestHelper(HttpListenerRequest request, string basepath)
        {
            this.request = request;
            this.basepath = basepath;
        }

        public delegate void ExecutingDispatch(FileStream fs);

        public void DispatchResources(ExecutingDispatch action)
        {
            string rawUrl = request.RawUrl;
            string rawPath = rawUrl.Replace("/", Path.DirectorySeparatorChar + "");
            //这里对应请求其他类型资源,如图片,文本等
            string filePath = string.Format(@"{0}{1}", basepath, rawPath);
            //默认文档为index.html
            if (rawUrl.Length == 1)
            {
                filePath = string.Format(@"{0}/index.html", basepath);
            }

            filePath = filePath.Replace(Path.DirectorySeparatorChar + "" + Path.DirectorySeparatorChar, Path.DirectorySeparatorChar + "");

            try
            {
                if (File.Exists(filePath))
                {
                    FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);

                    action?.Invoke(fs);
                }
            }
            catch { return; }
        }
    }
}

响应(ZResponseHelper)

代码语言:javascript
代码运行次数:0
运行
复制
using System;
using System.IO;
using System.Net;

namespace SchoolClient.Utils.HttpServer
{
    public class ZResponseHelper
    {
        private HttpListenerResponse response;

        public ZResponseHelper(HttpListenerResponse response)
        {
            this.response = response;
            outputStream = response.OutputStream;
        }

        public Stream outputStream { get; set; }

        public class FileObject
        {
            public FileStream fs;
            public byte[] buffer;
        }

        public void WriteToClient(FileStream fs)
        {
            response.StatusCode = 200;
            byte[] buffer = new byte[1024];
            FileObject obj = new FileObject() { fs = fs, buffer = buffer };
            fs.BeginRead(buffer, 0, buffer.Length, new AsyncCallback(EndWrite), obj);
        }

        private void EndWrite(IAsyncResult ar)
        {
            FileObject obj = ar.AsyncState as FileObject;
            int num = obj.fs.EndRead(ar);
            outputStream.Write(obj.buffer, 0, num);
            if (num < 1)
            {
                obj.fs.Close(); //关闭文件流
                outputStream.Close();//关闭输出流,如果不关闭,浏览器将一直在等待状态
                obj.fs.Dispose();
                outputStream.Dispose();
                return;
            }
            obj.fs.BeginRead(obj.buffer, 0, obj.buffer.Length, new AsyncCallback(EndWrite), obj);
        }
    }
}

调用

项目根目录创建文件夹wwwroot

属性=>生成事件=>生成前事件命令行中添加

代码语言:javascript
代码运行次数:0
运行
复制
xcopy /Y /i /e $(ProjectDir)\wwwroot $(TargetDir)\wwwroot

项目中启动

代码语言:javascript
代码运行次数:0
运行
复制
public static string basePath = AppDomain.CurrentDomain.BaseDirectory;
public static string wwwrootPath = $"{basePath}wwwroot\\";
public void startHttpServer()
{
    new Thread(
        o =>
        {
            new ZServerHelper().Setup(wwwrootPath, 8899);
        }
    )
    { IsBackground = true }
    .Start();
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-10-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 集成Nginx
  • C#实现
    • 工具类(ZServerHelper)
    • 请求(ZRequestHelper)
    • 响应(ZResponseHelper)
    • 调用
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档