后续:利用C#建立简单服务器

之前的博客 利用C#制作简单服务器 介绍了一个可以搭建简单服务器的类,但是有一个问题,这个服务器完全是基于虚拟路径的,即请求的文件位置在服务器上是根本不存在的。如果只是将这个服务器应用于单个类型请求的响应肯定是不够的,我们需要将这个服务器弄成可以针对不同虚拟路径进行不同响应的,于是对代码进行了以下修改:

using System;
using System.Collections.Generic;
using System.Net;

namespace HttpWebServer
{
    public delegate void RequestReceivedEventHandler(HttpListenerContext context);
    public class HttpWebServer:IDisposable
    {
        protected HttpListener _listener;
        protected bool _isListenerOn;
        
        public event RequestReceivedEventHandler OnRequestReceived;


        public HttpWebServer(HttpWebServerResponsor responsor)
        {
            OnRequestReceived += responsor.Response;
        }
        public void StartListening(string[] urlCollection)
        {
            _isListenerOn = true;
            _listener = new HttpListener();
            foreach (var i in urlCollection) _listener.Prefixes.Add(i);
            _listener.Start();
            Action requestLoop = new Action(delegate
            {
                while (_isListenerOn)
                {
                    _listener.BeginGetContext(new AsyncCallback(delegate (IAsyncResult ar)
                    {
                        OnRequestReceived(_listener.EndGetContext(ar));
                    }), null).AsyncWaitHandle.WaitOne();
                }
            });
            requestLoop.BeginInvoke(null, null);
        }

        public void StopListening()
        {
            if (_isListenerOn)
            {
                _isListenerOn = false;
                if (_listener != null)
                {
                    _listener.Stop();
                    _listener.Close();
                    _listener = null;
                }
            }
        }

        public void Dispose()
        {
            StopListening();
        }
    }
    public class HttpWebServerResponsor
    {
        public RequestReceivedEventHandler errorResponseMethod;
        private ServerCommandNode _rootNode;
        public ServerCommandNode RootNode { get => _rootNode; }
        public HttpWebServerResponsor()
        {
            _rootNode = new ServerCommandNode("");
        }
        public void Response(HttpListenerContext context)
        {
            string[] urlGroup = context.Request.RawUrl.Split('?')[0].Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
            ServerCommandNode node = _rootNode;
            RequestReceivedEventHandler responseMethod=null;
            foreach (var i in urlGroup)
            {
                node = node[i];
                if (node==null)
                {
                    responseMethod = errorResponseMethod;
                    break;
                }
            }
            if (node != null) responseMethod = node.RootResponseMethod;
            responseMethod?.Invoke(context);
            return;
        }
    }
    public class ServerCommandNode
    {
        string _name;
        Dictionary<string, ServerCommandNode> _serverNodes;
        public RequestReceivedEventHandler RootResponseMethod;
        public ServerCommandNode this[string nodeName] { get => _serverNodes[nodeName]; }
        public void AddNode(string name, RequestReceivedEventHandler requestReceived = null)
        {
            _serverNodes.Add(name, new ServerCommandNode(name, requestReceived));
        }
        public ServerCommandNode(string name, RequestReceivedEventHandler requestReceived = null)
        {
            _name = name;
            _serverNodes = new Dictionary<string, ServerCommandNode>();
            RootResponseMethod = requestReceived;
        }
    }
}

使用方法:

using System;
using System.IO;
using System.Net;
using System.Text;
using System.Windows.Forms;

namespace HttpWebServer
{
    public partial class Form1 : Form
    {
        private HttpWebServer webServer;
        public Form1()
        {
            InitializeComponent();
            HttpWebServerResponsor serverResponsor = new HttpWebServerResponsor();
            serverResponsor.RootNode.AddNode("chat", Response_chat);
            webServer = new HttpWebServer(serverResponsor);
            webServer.StartListening(new string[] { "http://127.0.0.1:14285/" });
        }
        private void Response_chat(HttpListenerContext context)
        {
            var reader = new StreamReader(context.Request.InputStream);
            var msg = reader.ReadToEnd();
            reader.Dispose();
            HttpListenerResponse response = context.Response;
            string responseString = null;
            var quaryString = context.Request.QueryString;
            string userId = context.Request.QueryString["user"];
            if (userId == null)
            {
                response.StatusCode = 233;
                response.StatusDescription = "No user";
                responseString = "error";
                Invoke(new MethodInvoker(delegate
                {
                    textBox1.Text += $"Anonymous:{msg}\r\n";
                }));

            }
            else
            {
                Invoke(new MethodInvoker(delegate
                {
                    textBox1.Text += $"{userId}:{msg}\r\n";
                }));
                response.StatusCode = 200;
                responseString = "ok";
            }
            byte[] buffer = Encoding.UTF8.GetBytes(responseString);
            response.ContentLength64 = buffer.Length;
            Stream output = response.OutputStream;
            output.Write(buffer, 0, buffer.Length);
            output.Close();
        }
    }
}

 

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值