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[].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 = ;
context.Response.StatusDescription = "Internal Server Error";
context.Response.Close();
Console.WriteLine("Error processing HTTP request\n{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\n{0}", ex);
}
catch (Exception ex)
{
HttpListenerException httpException = ex as HttpListenerException;
if (httpException == null || httpException.ErrorCode != )// IO operation aborted
{
Console.WriteLine("Error processing HTTP request\n{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();
}
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[]); 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 = ;
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", , "NOT FOUND");
} private static async Task WriteString(HttpListenerContext context, string data, string contentType,
int httpStatus = , 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, , 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, , 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", "");
} 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) { }
}
}
}

C# HTTPServer和OrleansClient结合的更多相关文章

  1. NodeJS 最快速搭建一个HttpServer

    最快速搭建一个HttpServer 在目录里放一个index.html cd D:\Web\InternalWeb start http-server -i -p 8081

  2. 基于Netty4的HttpServer和HttpClient的简单实现

    Netty的主页:http://netty.io/index.html 使用的Netty的版本:netty-4.0.23.Final.tar.bz2 ‐ 15-Aug-2014 (Stable, Re ...

  3. libevent源码分析:http-server例子

    http-server例子是libevent提供的一个简单web服务器,实现了对静态网页的处理功能. /* * gcc -g -o http-server http-server.c -levent ...

  4. httpserver

    改了下 # -*- coding:utf-8 -*- from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler HOST = &quo ...

  5. 一个简单的零配置命令行HTTP服务器 - http-server (nodeJs)

    http-server 是一个简单的零配置命令行HTTP服务器, 基于 nodeJs. 如果你不想重复的写 nodeJs 的 web-server.js, 则可以使用这个. 安装 (全局安装加 -g) ...

  6. nodejs搭建http-server

      很多时候我们都需要搭建一个简单的服务器,部署在IIS,阿帕奇,或者用nodejs,网上很多关于nodejs搭建server的文章,但都是要创建server.js,很麻烦, 在这里我分享一个创建ht ...

  7. 一、HTTPServer,RequestHandler,ServerHandler,Handler

    1.      HTTPServer,RequestHandler,ServerHandler,Handler 1.1       基本概念 HTTPServer主要是对传输控制层HTTP,TCP,S ...

  8. nodejs:本地文件夹http服务器http-server

    一.已经安装nodejs的电脑,有一个方便通过http访问本地文件夹.文件夹服务器 static files over HTTP,并不是我们平常说的node那个web服务器哦 二.好处 可以方便实现跨 ...

  9. PHP使用libevent实现高性能httpServer

    今天发现php也有一个libevent的扩展,安装后尝试下了一个webserver(httpserver), 发现性能还不错,逻辑很简单,每秒响应速度1800~4000次/s 代码如下 <?ph ...

随机推荐

  1. 原创:vsphere概念深入系列三:vSphere命令行管理

    假设无法近距离接触物理主机,只能远程命令行管理,. 以下命令行可以起到点作用. 首先需要安装vSphere CLI工具. 启动后界面: 1.查看datastore内容 所有命令行工具都可以加上-ser ...

  2. Centos或Windows中部署Zookeeper集群及其简单用法

    一.简介 ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件.它是一个为分布式应用提供一致性服务的软件 ...

  3. Git操作简单入门及相关命令

    说明:本文内容主要来自文末参考链接内容,此文仅作学习记录.如有转载,请到文末参考链接处. 1 基本概念理解 1.1 Git介绍 Git是分布式版本控制系统. 集中式VS分布式,SVN VS Git. ...

  4. VTK拾取网格模型上的可见点

    消隐与Z-Buffer 使用缓冲器记录物体表面在屏幕上投影所覆盖范围内的全部像素的深度值,依次访问屏幕范围内物体表面所覆盖的每一像素,用深度小(深度用z值表示,z值小表示离视点近)的像素点颜色替代深度 ...

  5. 对象拷贝:jQuery extend

    今天操作一个Array数组对象,本来想着先取出该数组某一行数据,然后把该数据当作另一份数据进行操作. 结果发现,对该数据操作的同时,也对Array数组进行了修改,因为这个数据指向了array数组对象. ...

  6. Jmeter远程测试

    11.3 详解JMeter远程测试(1) 2012-04-09 09:14 温素剑 电子工业出版社 字号:T | T 综合评级: 想读(7)  在读(2)  已读(0)   品书斋鉴(0)   已有9 ...

  7. android makefile文件批量拷贝文件的方法

    该方法是shell 和makefile组合使用 wallpapers := $(shell ls packages/apps/hyst_apps/NewBingoLauncher_C/default_ ...

  8. 阿里云centos7.x 打开80端口(转)

    本文转自:https://blog.csdn.net/tengqingyong/article/details/82805053 一 :阿里云centos7.x用iptables打开80端口 1.安装 ...

  9. IDEA使用笔记(七)——编辑器最大个数的设置

    我想一定有许多人和我一样在使用IDEA的时候,打开了许多的编辑器选项卡,但是打开的数量是有限的,我们想打开更多的页面,并且希望控制当再次达到大限的时候能关闭那些我们最久没有看的文件! 好吧!看下面的配 ...

  10. 记一次性能优化,限制tcp_timewait数量,快速回收和重用

    前言 这篇文章的主题是记录一次Python程序的性能优化,在优化的过程中遇到的问题,以及如何去解决的.为大家提供一个优化的思路,首先要声明的一点是,我的方式不是唯一的,大家在性能优化之路上遇到的问题都 ...