HTTP服务器实现之——C#

之前一直用的Http服务一直是Java写的,因为没有门语言都可实现HTTP服务,所以今天,我用C# 写了一个HTTP服务,分享出来,供大家探讨。

C#实现HTTP服务,那就要用到.Net的System.Net库。用 HttpListener类,来创建HTTP服务。

1.创建一个项目,模板用

HTTP服务器实现之——C#

2.创建一个HTTPServer类,来启动和监听接口(直接上代码)

 class HttpServer
    {
        private HttpListener listener = new HttpListener();
        private Dictionary<string, Action<string>> actionDict = new Dictionary<string, Action<string>>();
        private MyData mydata;

        public void AddPrefixes(string url, Action<string> action)
        {
            actionDict.Add(url, action);
        }

        //开始监听
        public void Start(int port)
        {
            if (!HttpListener.IsSupported)
            {
                Console.WriteLine("无法在当前系统上运行服务(Windows XP SP2 or Server 2003)。" + DateTime.Now.ToString());
                return;
            }

            if (actionDict.Count <= 0)
            {
                System.Console.WriteLine("没有监听端口");
            }

            foreach (var item in actionDict)
            {
                var url = string.Format("http://127.0.0.1:{0}{1}", port, item.Key + "/");
                System.Console.WriteLine(url);
                listener.Prefixes.Add(url);  //监听的是以item.Key + "/"+XXX接口

            }

            listener.Start();
            listener.BeginGetContext(Result, null);
            mydata = new MyData();

            System.Console.WriteLine("开始监听");
            System.Console.Read();
        }

        private void Result(IAsyncResult asy)
        {
            listener.BeginGetContext(Result, null);
            var context = listener.EndGetContext(asy);
            var req = context.Request;
            var rsp = context.Response;

            // 
            rsp.StatusCode = 200;
            rsp.ContentType = "text/plain;charset=UTF-8";//告诉客户端返回的ContentType类型为纯文本格式,编码为UTF-8
            rsp.AddHeader("Content-type", "text/plain");//添加响应头信息
            rsp.ContentEncoding = Encoding.UTF8;
                        //对接口所传数据处理
            HandleHttpMethod(context);
                        //对接口处理
            HandlerReq(req.RawUrl);
            try
            {
                using(var stream = rsp.OutputStream)
                {
                    ///获取数据,要返回给接口的
                    string data = mydata.GetMyData();
                    byte[] dataByte = Encoding.UTF8.GetBytes(data);
                    stream.Write(dataByte, 0, data.Length);
                }
            }
            catch (Exception e)
            {
                rsp.Close();
                System.Console.WriteLine(e);

            }
            rsp.Close();

        }

        /// <summary>
        /// 对客户端来的url处理
        /// </summary>
        /// <param name="url"></param>
        private void HandlerReq(string url)
        {
            try
            {
                System.Console.WriteLine("url : " + url);

                foreach (var item in actionDict.Keys)
                {
                    System.Console.WriteLine(item);
                }

                string subUrl = url.Substring(1);
                int urlIndex = subUrl.IndexOf("/");
                subUrl = url.Substring(0, urlIndex+1);
                Console.WriteLine(subUrl);
                var action = actionDict[subUrl];
                action(url);
            }
            catch (Exception e)
            {
                System.Console.WriteLine(e);
            }
        }
        //处理接口所传数据 Post和Get
        private void HandleHttpMethod(HttpListenerContext context)
        {
            if(context.Request.ContentType != "text/plain")
            {
                Console.WriteLine("参数格式错误");
                return;
            }
            switch (context.Request.HttpMethod)
            {
                case "POST":

                    string contextLength = context.Request.Headers.GetValues("Content-Length")[0];

                    using (Stream stream = context.Request.InputStream)
                    {
                        StreamReader reader = new StreamReader(stream, Encoding.UTF8);
                        string content = reader.ReadToEnd();
                        System.Console.WriteLine(content);
                        int length = content.Length;
                        ///解析  接口所传数据
                    }
                    break;
                case "GET":
                    var data = context.Request.QueryString;
                    break;
            }
        }

    }

3.实现返回给客户端数据类,数据可以是通过http请求得到,也可以是从数据库查询得到(转5)

    class MyData
    {

        /// <summary>
        /// 获取数据
        /// </summary>
        /// <returns></returns>
        public string GetMyData()
        {
            return "cesh";
        }
    }

4.启动实现,定义端口

 static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        static void Main()
        {
            HttpServer httpServer = new HttpServer();

            httpServer.AddPrefixes("/test", (value) => {
                System.Console.WriteLine("test" + value);
            });

            httpServer.AddPrefixes("/vac", (value) => {
                System.Console.WriteLine("vac" + value);

            });
            httpServer.Start(8080);
        }
    }

5.实现Http请求数据

 private static string data;
        /// <summary>
        /// 获取数据
        /// </summary>
        /// <returns></returns>

        public string GetMyData()
        {
            new Task(() =>
            {
                Invoke();
            }).Start();
            Console.WriteLine("我是主线程");

            if (data == null) return null;
            return data;
        }

        public static async Task<string> Invoke()
        {
            var result = GetPostLoad();
            data = await result;  //等待返回
            Console.WriteLine(data);  //输出返回
            return data;
        }

        public static async Task<string> GetPostLoad()
        {
            HttpWebRequest request = WebRequest.Create("http:/*****************") as HttpWebRequest;
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded; charset=UTF-8";     //这里一定不要忘记了 我排查了好久 发现这里没有写这一句  弄的怀疑人生了 后来通过抓包对比 才发现这个差距  粗心了
            string data = "userId=123&agentId=456&companyId=789&versionTime=165665430918";
            byte[] buf = System.Text.Encoding.GetEncoding("UTF-8").GetBytes(data);
            request.ContentLength = buf.Length;
            Stream newStream = request.GetRequestStream();
            newStream.Write(buf, 0, buf.Length);
            newStream.Close();
            HttpWebResponse response = await request.GetResponseAsync() as HttpWebResponse;
            StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding("UTF-8"));
            string result = reader.ReadToEnd();
            return result;
        }

好了,至于扩展的话,就在MyData类里面扩展就好了。

HTTP服务器实现之——C#

上一篇:Sql Server助手类


下一篇:WPF 如何:实现 ICommandSource