我们知道,借助OWIN,WebApi,SignalR,WCF 都可以创建自托管(Self-Host)实例,完全不需要IIS,静态网站也可以。
最近做一个服务器监控小工具,用 SignalR 通信,监控端是一个静态网站(挂在IIS),服务端是一个 WinForm 程序(SignalR 服务寄宿),但是我想网站也寄宿到这个 WinForm 中,这样通过 WebApp.Start 开启主机时,网站也开启了,部署也方便
为了减少配置代码,我们用一个静态文件处理的中间件 Beginor.Owin.StaticFile
Install-Package Beginor.Owin.StaticFile
在 OWIN 启动类中配置
using Beginor.Owin.StaticFile; [assembly: OwinStartup(typeof(AisinGioro.Server.OwinStartup))] namespace AisinGioro.Server { public class OwinStartup { public void Configuration(IAppBuilder app) { //静态文件托管 app.Map("/wwwroot", map => { // 允许跨域 map.UseCors(CorsOptions.AllowAll); map.UseStaticFile(new StaticFileMiddlewareOptions { RootDirectory = @"D:\P22\Felix\AisinGioro\AisinGioro.WebPortal", DefaultFile = "index.html", EnableETag = true, EnableHtml5LocationMode = true, MimeTypeProvider = new MimeTypeProvider(new Dictionary<string, string> { { ".html", "text/html" }, { ".htm", "text/html" }, { ".dtd", "text/xml" }, { ".xml", "text/xml" }, { ".ico", "image/x-icon" }, { ".css", "text/css" }, { ".js", "application/javascript" }, { ".json", "application/json" }, { ".jpg", "image/jpeg" }, { ".png", "image/png" }, { ".gif", "image/gif" }, { ".config", "text/xml" }, { ".woff2", "application/font-woff2"}, { ".eot", "application/vnd.ms-fontobject" }, { ".svg", "image/svg+xml" }, { ".woff", "font/x-woff" }, { ".txt", "text/plain" }, { ".log", "text/plain" } }) }); }); //SignalR托管 app.Map("/signalr", map => { // 允许跨域 map.UseCors(CorsOptions.AllowAll); var hubConfiguration = new HubConfiguration { //Resolver = **, // You can enable JSONP by uncommenting line below. // JSONP requests are insecure but some older browsers (and some // versions of IE) require JSONP to work cross domain EnableJSONP = true, EnableDetailedErrors = true }; // Run the SignalR pipeline. We‘re not using MapSignalR // since this branch is already runs under the "/signalr" // path. map.RunSignalR(hubConfiguration); }); //该值表示连接在超时之前保持打开状态的时间长度。 //默认为110秒 //GlobalHost.Configuration.ConnectionTimeout = TimeSpan.FromSeconds(110); //该值表示在连接停止之后引发断开连接事件之前要等待的时间长度。 //默认为30秒 GlobalHost.Configuration.DisconnectTimeout = TimeSpan.FromSeconds(60); } } }
其中 RootDirectory 也可以配置相对目录,比如 ../app/wwwroot
MimeTypeProvider 属性设置 MIME 映射(Content-Type),如果不设置,Beginor.Owin.StaticFile 只能能判断普通的类型(比如 html,css,js),所以还是设置下比较好
创建Web服务监听,开启主机
private void DoWork() { try { //创建WEB服务器监听 using (WebApp.Start<OwinStartup>(_hostUrl)) { if (this.OnStartSucceed != null) this.OnStartSucceed(this, EventArgs.Empty); LogHelper.Trace("Server started! {0}", _hostUrl); while (!cancelTokenSource.IsCancellationRequested) Thread.Sleep(10); } LogHelper.Trace("Server stopped!"); if (this.OnStopSucceed != null) this.OnStopSucceed(this, EventArgs.Empty); //Server stopped! } catch (Exception ex) { ex = ex.GetBaseException(); LogHelper.Error(ex.Message + " " + _hostUrl); if (this.OnFailed != null) this.OnFailed(this, new ErrorOccuredEventArgs(ex)); } }
如果外部程序执行 cancelTokenSource.Cancel,主机服务停止运行
=========================
客户端连接SignalR用这个地址:http://localhost:9000/signalr
而访问网站,用这个地址:http://localhost:9000/wwwroot/