vs2013和.net 4.5.1调用.net core中的Kestrel(基于libuv)的http服务器代码 两种方式
nuget获取相关的包:两个:Microsoft.AspNetCore.Server.Kestrel 和 Microsoft.Extensions.Logging.Console
编译完成后手工将package 中的libuv下的libuv.dll拷贝到你的exe目录。
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace KingUvHttp
{
class Program
{
static void Main(string[] args)
{
Http1();
Http2();
}
static void Http1()
{
UvHttpServer server = new UvHttpServer();
//注意,这里不能用"localhost"这种,必须是明确的ip地址。
server.Addresses.Add("http://0.0.0.0:5000");
var app = new HxzHttpApplication();
server.Start(app);
}
static void Http2()
{
var host = new WebHostBuilder()
.UseKestrel(options =>
{
// options.ThreadCount = 4;
options.NoDelay = true;
options.UseConnectionLogging();
})
.UseUrls("http://127.0.0.1:5001")
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.Build();
host.Run();
}
}
public class Startup
{
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(LogLevel.Trace);
app.Run(async context =>
{
Console.WriteLine("{0} {1}{2}{3}",
context.Request.Method,
context.Request.PathBase,
context.Request.Path,
context.Request.QueryString);
Console.WriteLine("Method:{0}",context.Request.Method);
Console.WriteLine("PathBase:{0}",context.Request.PathBase);
Console.WriteLine("Path:{0}",context.Request.Path);
Console.WriteLine("QueryString:{0}",context.Request.QueryString);
var connectionFeature = context.Connection;
Console.WriteLine("Peer:{0}",connectionFeature.RemoteIpAddress.ToString());
Console.WriteLine("Sock:{0}",connectionFeature.LocalIpAddress.ToString());
context.Response.ContentLength = 11;
context.Response.ContentType = "text/plain";
await context.Response.WriteAsync("Hello world");
});
}
}
}
using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.AspNetCore.Server.Kestrel;
using Microsoft.AspNetCore.Server.Kestrel.Internal;
using Microsoft.AspNetCore.Server.Kestrel.Internal.Http;
using Microsoft.AspNetCore.Server.Kestrel.Internal.Infrastructure;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace KingUvHttp
{
public class UvHttpServer
{
private Stack<IDisposable> _disposables;
public UvHttpServer()
{
Options = new KestrelServerOptions();
Addresses = new List<string>();
lf.AddConsole();
_logger = lf.CreateLogger("UvHttpServer");
}
public LoggerFactory lf = new LoggerFactory();
public HxzApplicationLifetime AppLt { get; set; }
public KestrelServerOptions Options { get; set; }
public List<string> Addresses { get; set; }
public ILogger _logger { get; set; }
public void Start<TContext>(IHttpApplication<TContext> application)
{
if (_disposables != null)
{
// The server has already started and/or has not been cleaned up yet
throw new InvalidOperationException("Server has already started.");
}
_disposables = new Stack<IDisposable>();
try
{
var dateHeaderValueManager = new DateHeaderValueManager();
var trace = new KestrelTrace(_logger);
var engine = new KestrelEngine(new ServiceContext
{
FrameFactory = context =>
{
return new Frame<TContext>(application, context);
},
AppLifetime = AppLt,
Log = trace,
ThreadPool = new LoggingThreadPool(trace),
DateHeaderValueManager = dateHeaderValueManager,
ServerOptions = Options
});
_disposables.Push(engine);
_disposables.Push(dateHeaderValueManager);
var threadCount = Options.ThreadCount;
if (threadCount <= 0)
{
throw new ArgumentOutOfRangeException("threadCount",
threadCount,
"ThreadCount must be positive.");
}
engine.Start(threadCount);
var atLeastOneListener = false;
foreach (var address in Addresses.ToArray())
{
var parsedAddress = ServerAddress.FromUrl(address);
atLeastOneListener = true;
_disposables.Push(engine.CreateServer(parsedAddress));
Addresses.Remove(address);
Addresses.Add(parsedAddress.ToString());
}
if (!atLeastOneListener)
{
throw new InvalidOperationException("No recognized listening addresses were configured.");
}
}
catch (Exception e)
{
Dispose();
throw;
}
}
public void Dispose()
{
if (_disposables != null)
{
while (_disposables.Count > 0)
{
_disposables.Pop().Dispose();
}
_disposables = null;
}
}
}
}
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Server.Kestrel;
using Microsoft.AspNetCore.Server.Kestrel.Internal.Http;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace KingUvHttp
{
public class HttpCtx
{
public Frame<HttpCtx> frame { get; set; }
}
public class HxzHttpApplication : IHttpApplication<HttpCtx>
{
public HttpCtx CreateContext(IFeatureCollection contextFeatures)
{
HttpCtx ctx = new HttpCtx();
ctx.frame = (Frame<HttpCtx>)contextFeatures;
return ctx;
}
public void DisposeContext(HttpCtx context, Exception exception)
{
}
public Task ProcessRequestAsync(HttpCtx context)
{
Console.WriteLine("Method:{0}", context.frame.Method);
Console.WriteLine("PathBase:{0}", context.frame.PathBase);
Console.WriteLine("Path:{0}", context.frame.Path);
Console.WriteLine("QueryString:{0}", context.frame.QueryString);
Console.WriteLine("Peer:{0}", context.frame.RemoteEndPoint.ToString());
Console.WriteLine("Sock:{0}", context.frame.LocalEndPoint.ToString());
return Task.Factory.StartNew(() =>
{
var enc = System.Text.Encoding.UTF8;
byte[] rspbin = enc.GetBytes("hello,world");
context.frame.ResponseBody.WriteAsync(rspbin, 0, rspbin.Length);
});
}
}
public class HxzServiceProvider : IServiceProvider
{
public object GetService(Type serviceType)
{
if (serviceType == typeof(ILoggerFactory))
{
return ilf;
}
return null;
}
private static ILoggerFactory ilf = new LoggerFactory();
}
public class HxzApplicationLifetime : IApplicationLifetime
{
public CancellationToken ApplicationStarted
{
get
{
throw new NotImplementedException();
}
}
public CancellationToken ApplicationStopped
{
get
{
throw new NotImplementedException();
}
}
public CancellationToken ApplicationStopping
{
get
{
throw new NotImplementedException();
}
}
public void StopApplication()
{
throw new NotImplementedException();
}
}
public class HxzOptions : IOptions<KestrelServerOptions>
{
public KestrelServerOptions Value { get; set; }
}
}