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);
            }
        }


    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM