之前一直用的Http服务一直是Java写的,因为没有门语言都可实现HTTP服务,所以今天,我用C# 写了一个HTTP服务,分享出来,供大家探讨。
C#实现HTTP服务,那就要用到.Net的System.Net库。用 HttpListener类,来创建HTTP服务。
1.创建一个项目,模板用
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类里面扩展就好了。