• C# HTTPServer和OrleansClient结合


    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.IO.Compression;
    using System.Linq;
    using System.Net;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Threading;
    using System.Threading.Tasks;
    using GrainInterface;
    using Newtonsoft.Json;
    using Orleans;
    
    namespace PayServer
    {
        public class HttpServer
        {
            private const string NotFoundResponse = "<!doctype html><html><body>Resource not found</body></html>";
            private readonly HttpListener httpListener;
            private readonly CancellationTokenSource cts = new CancellationTokenSource();
            private readonly string prefixPath;
    
            private Task processingTask;
    
            public HttpServer(string listenerUriPrefix)
            {
                this.prefixPath = ParsePrefixPath(listenerUriPrefix);
                this.httpListener = new HttpListener();
                this.httpListener.Prefixes.Add(listenerUriPrefix);
            }
    
            private static string ParsePrefixPath(string listenerUriPrefix)
            {
                var match = Regex.Match(listenerUriPrefix, @"http://(?:[^/]*)(?::d+)?/(.*)");
                if (match.Success)
                {
                    return match.Groups[1].Value.ToLowerInvariant();
                }
                else
                {
                    return string.Empty;
                }
            }
    
            public void Start()
            {
                this.httpListener.Start();
                this.processingTask = Task.Factory.StartNew(async () => await ProcessRequests(), TaskCreationOptions.LongRunning);
            }
    
            private async Task ProcessRequests()
            {
                while (!this.cts.IsCancellationRequested)
                {
                    try
                    {
                        var context = await this.httpListener.GetContextAsync();
                        try
                        {
                            await ProcessRequest(context).ConfigureAwait(false);
                            context.Response.Close();
                        }
                        catch (Exception ex)
                        {
                            context.Response.StatusCode = 500;
                            context.Response.StatusDescription = "Internal Server Error";
                            context.Response.Close();
                            Console.WriteLine("Error processing HTTP request
    {0}", ex);
                        }
                    }
                    catch (ObjectDisposedException ex)
                    {
                        if ((ex.ObjectName == this.httpListener.GetType().FullName) && (this.httpListener.IsListening == false))
                        {
                            return; // listener is closed/disposed
                        }
                        Console.WriteLine("Error processing HTTP request
    {0}", ex);
                    }
                    catch (Exception ex)
                    {
                        HttpListenerException httpException = ex as HttpListenerException;
                        if (httpException == null || httpException.ErrorCode != 995)// IO operation aborted
                        {
                            Console.WriteLine("Error processing HTTP request
    {0}", ex);
                        }
                    }
                }
            }
    
            private Task ProcessRequest(HttpListenerContext context)
            {
                if (context.Request.HttpMethod.ToUpperInvariant() != "GET")
                {
                    return WriteNotFound(context);
                }
    
                var urlPath = context.Request.RawUrl.Substring(this.prefixPath.Length)
                    .ToLowerInvariant();
    
                switch (urlPath)
                {
                    case "/":
                        if (!context.Request.Url.ToString().EndsWith("/"))
                        {
                            context.Response.Redirect(context.Request.Url + "/");
                            context.Response.Close();
                            return Task.FromResult(0);
                        }
                        else
                        {
                            return WriteString(context, "Hello World!", "text/plain");
                        }
                    case "/favicon.ico":
                        return WriteFavIcon(context);
                    case "/ping":
                        return WritePong(context);
                    case "/pay":
                        return OnPayResult(context);
                }
                return WriteNotFound(context);
            }
    
            private static Task WritePong(HttpListenerContext context)
            {
                return WriteString(context, "pong", "text/plain");
            }
    
            private static async Task OnPayResult(HttpListenerContext context)
            {
                var ret = "failed";
                try
                {
                    string postData;
                    using (var br = new BinaryReader(context.Request.InputStream))
                    {
                        postData =
                            Encoding.UTF8.GetString(
                                br.ReadBytes(int.Parse(context.Request.ContentLength64.ToString())));
                    }
                    if (!string.IsNullOrEmpty(postData))
                    {
                        Console.WriteLine("postData=[{0}]", postData);
    
                        var request = JsonConvert.DeserializeObject<PayResult>(postData);
                        if (null != request)
                        {
                            var parmas = request.data.orderNo.Split(',');
    
                            var id = long.Parse(parmas[0]);
    
                            var playerProxy = GrainClient.GrainFactory.GetGrain<IPlayerProxy>(id);
                            var success =
                                await playerProxy.OnPlayerPayResult(request.data.orderNo, request.code, request.msg);
                            if (success)
                            {
                                ret = "success";
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                }
                
                await WriteString(context, ret, "text/plain");
            }
    
            private static async Task WriteFavIcon(HttpListenerContext context)
            {
                context.Response.ContentType = "image/png";
                context.Response.StatusCode = 200;
                context.Response.StatusDescription = "OK";
                using (var stream = File.Open("icon.png", FileMode.Open))
                {
                    var output = context.Response.OutputStream;
                    await stream.CopyToAsync(output);
                }
            }
    
            private static Task WriteNotFound(HttpListenerContext context)
            {
                return WriteString(context, NotFoundResponse, "text/plain", 404, "NOT FOUND");
            }
    
            private static async Task WriteString(HttpListenerContext context, string data, string contentType,
                int httpStatus = 200, string httpStatusDescription = "OK")
            {
                AddCORSHeaders(context.Response);
                AddNoCacheHeaders(context.Response);
    
                context.Response.ContentType = contentType;
                context.Response.StatusCode = httpStatus;
                context.Response.StatusDescription = httpStatusDescription;
    
                var acceptsGzip = AcceptsGzip(context.Request);
                if (!acceptsGzip)
                {
                    using (var writer = new StreamWriter(context.Response.OutputStream, Encoding.UTF8, 4096, true))
                    {
                        await writer.WriteAsync(data).ConfigureAwait(false);
                    }
                }
                else
                {
                    context.Response.AddHeader("Content-Encoding", "gzip");
                    using (GZipStream gzip = new GZipStream(context.Response.OutputStream, CompressionMode.Compress, true))
                    using (var writer = new StreamWriter(gzip, Encoding.UTF8, 4096, true))
                    {
                        await writer.WriteAsync(data).ConfigureAwait(false);
                    }
                }
            }
    
    
            private static bool AcceptsGzip(HttpListenerRequest request)
            {
                string encoding = request.Headers["Accept-Encoding"];
                if (string.IsNullOrEmpty(encoding))
                {
                    return false;
                }
    
                return encoding.Contains("gzip");
            }
    
            private static void AddNoCacheHeaders(HttpListenerResponse response)
            {
                response.Headers.Add("Cache-Control", "no-cache, no-store, must-revalidate");
                response.Headers.Add("Pragma", "no-cache");
                response.Headers.Add("Expires", "0");
            }
    
            private static void AddCORSHeaders(HttpListenerResponse response)
            {
                response.Headers.Add("Access-Control-Allow-Origin", "*");
                response.Headers.Add("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
            }
    
            private void Stop()
            {
                cts.Cancel();
                if (processingTask != null && !processingTask.IsCompleted)
                {
                    processingTask.Wait();
                }
                if (this.httpListener.IsListening)
                {
                    this.httpListener.Stop();
                    this.httpListener.Prefixes.Clear();
                }
            }
    
            public void Dispose()
            {
                this.Stop();
                this.httpListener.Close();
                using (this.cts) { }
                using (this.httpListener) { }
            }
        }
    }
  • 相关阅读:
    《人月神话》读书笔记二
    正则表达式进阶篇
    Zend Framework学习之自定义认证适配器
    Zend Framework学习之常用校验器
    Zend Framework学习之Zend_Mail
    《人月神话》读书笔记一
    Zend Framework学习之校验器Zend_Validate
    我的第一个C++程序
    Zend Framework学习之Zend_Filter_StripTags
    《黑客与画家》读书笔记三(完结)
  • 原文地址:https://www.cnblogs.com/mrblue/p/8550630.html
Copyright © 2020-2023  润新知