C# HttpListener 的使用方法

关于监听回调两次的原因,可能是因为重新监听导致的,所以查到微软上面的解析是说

BeginGetContext方法开始异步 (非阻塞) 调用以接收传入的客户端请求。 在调用此方法之前,必须调用 Start 方法,并添加至少一个统一资源标识符 (uri) 前缀,以便通过将 uri 字符串添加到属性返回的来侦听 HttpListenerPrefixCollection Prefixes

必须通过调用方法完成异步操作 EndGetContext通常,方法由 callback 委托调用。

操作完成时,此方法不会被阻止。 若要获取传入请求并在操作完成之前一直阻止,请调用 GetContext 方法。

有关使用异步编程模型的详细信息,请参阅 以异步方式调用同步方法

 

我的猜测是这个

 

下面是写的一个HttpListener 帮助类

 public class HttpListenerServer : IDisposable
    {
        private readonly HttpListener _listener;
       
        public HttpListenerServer(string[] prefixes)
        { // 检查系统是否支持
            if (!HttpListener.IsSupported)
            {
                throw new ArgumentException("使用 该功能的系统 必须为 Windows XP SP2 或 Server 2003 以上系统!");
            }
            if (prefixes == null || prefixes.Length == 0) 
            {
                throw new ArgumentException("请填写监听地址");
            }
            _listener = new HttpListener();
            foreach (string s in prefixes)
            {
                _listener.Prefixes.Add(s);
            }
            _listener.Start();
            _listener.BeginGetContext(new AsyncCallback(GetContextCallBack), _listener);
        }
        public void Dispose()
        {
            try
            {
                if (_listener != null)
                {
                    _listener.Stop();
                    _listener.Close();
                    _listener.Abort();
                }
                RequestHandlerEven = null;
            }
            catch (Exception)
            {


            }
        }

     

        public delegate object RequestHandler(HttpListenerRequest request);
        public event RequestHandler RequestHandlerEven;
        private void GetContextCallBack(IAsyncResult ar)
        {
            try
            {
                HttpListener httplis = ar.AsyncState as HttpListener;
                if (httplis.IsListening)
                {
                    HttpListenerContext context = httplis.EndGetContext(ar);
                    #region 解析Request请求
                    object resData = null;
                    HttpListenerRequest request = context.Request;
                    if (RequestHandlerEven != null)
                    {
                        resData = RequestHandlerEven(request);
                    }
                    else
                    {
                        resData = new
                        {
                            code = "200",
                            description = "成功",
                            data = "接收数据完成,时间:=" + DateTime.Now
                        };
                    }
                    #endregion 解析Request请求
                    #region 构造Response响应

                    using (HttpListenerResponse response = context.Response)
                    {
                        response.ContentEncoding = Encoding.UTF8;
                        response.ContentType = "application/json;charset=UTF-8";
                        response.AppendHeader("Content-Type", "application/json;charset=UTF-8");
                        try
                        {
                            response.StatusCode = (int)HttpStatusCode.OK;
                            string responseString = JsonConvert.SerializeObject(resData, new JsonSerializerSettings() { StringEscapeHandling = StringEscapeHandling.EscapeNonAscii });
                            using (StreamWriter writer = new StreamWriter(response.OutputStream, Encoding.UTF8))
                            {
                                writer.Write(responseString);
                                writer.Close();
                                response.Close();
                            }
                        }
                        catch (Exception ex)
                        {
                            response.StatusCode = (int)HttpStatusCode.NotFound;
                            response.StatusDescription = "404";
                            Console.ForegroundColor = ConsoleColor.Red;
                            Console.WriteLine($"在接收数据时发生错误:{ex.ToString()}");
                            //把服务端错误信息直接返回可能会导致信息不安全,此处仅供参考
                            var returnByteArr = Encoding.UTF8.GetBytes($"在接收数据时发生错误:{ex.ToString()}");//设置客户端返回信息的编码
                            using (var stream = response.OutputStream)
                            {
                                //把处理信息返回到客户端
                                stream.Write(returnByteArr, 0, returnByteArr.Length);
                                stream.Close();
                                response.Close();
                            }
                        }
                    }
                    #endregion 构造Response响应
                    httplis.GetContext();
                    _listener.BeginGetContext(new AsyncCallback(GetContextCallBack), _listener);
                }
            }
            catch (Exception ex)
            {
                throw new ArgumentException(ex.Message);
            }
        }


    }

 

posted @ 2022-02-21 15:40  LuoCore  阅读(2980)  评论(1编辑  收藏  举报