隐藏

C# Owin快速搭建网站(免IIS),一个.exe文件即是一个服务器

发布:2020/7/7 17:51:50作者:管理员 来源:本站 浏览次数:2776

界面:

 

结构:

    一、新建winform工程

    NuGet安装以下几个包:

(1):Microsoft.AspNet.WebApi.OwinSelfHost

 

(2):Microsoft.AspNet.SignalR

(3)静态文件处理的中间件:Beginor.Owin.StaticFile

(4)Microsoft.Owin.Cors

 

(5) 将其他dll打包成一个exe:Costura.Fody

 

     二、代码

启动类:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    using OwinTest2.model;
    using OwinTest2.view;
     
    namespace OwinTest2
    {
        static class Program
        {
            /// <summary>
            /// 应用程序的主入口点。
            /// </summary>
            [STAThread]
            static void Main()
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(GlobalData.GetForm1());
            }
        }
    }

 

Form1 类:

    using System;
    using System.Net;
    using System.Threading;
    using System.Windows.Forms;
    using Microsoft.Owin.Hosting;
    using OwinTest2.server;
    using OwinTest2.model;
     
    namespace OwinTest2.view
    {
        public partial class Form1 : Form
        {
            //Owin服务实例对象
            private IDisposable disposeable;
     
            public Form1()
            {
                InitializeComponent();
                Init();
            }
     
            private void Init()
            {
                //非主线程亦可操作界面
                CheckForIllegalCrossThreadCalls = false;
                log_textBox.Text = "日志:\r\n";
                SetLog("开始获取本机IP...");
                //获取本机IP
                IPHostEntry here = Dns.GetHostEntry(Dns.GetHostName());
                foreach (IPAddress _ip in here.AddressList)
                {
                    if (_ip.AddressFamily.ToString().ToUpper() == "INTERNETWORK")
                    {
                        GlobalData.ServerIp = _ip.ToString();
                        //GlobalData.Port = (9000 + new Random().Next(1000)).ToString();
                        new Thread(() =>
                        {
                            //本地Http服务器
                            string baseAddress = "http://" + GlobalData.ServerIp + ":" + GlobalData.Port;
                            disposeable = WebApp.Start<Startup>(url: baseAddress);
                        })
                        { Name = "获取日志线程" }.Start();
                        break;
                    }
                }
                this.Text = this.Text + "  " + GlobalData.ServerIp + ":" + GlobalData.Port;
                SetLog("本机IP端口:" + GlobalData.ServerIp + ":" + GlobalData.Port);
            }
     
            public void SetLog(string log)
            {
                log_textBox.AppendText(log + "\r\n");
            }
     
            private void Form1_FormClosing(object sender, FormClosingEventArgs e)
            {
                DialogResult result = MessageBox.Show("确认退出吗?", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Information);
                if (result == DialogResult.OK)
                {
                    disposeable.Dispose();
                    //Dispose();
                    //Application.Exit();
                    System.Environment.Exit(0);
                }
                else
                {
                    e.Cancel = true;
                }
            }
        }
    }

Startup 配置类:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net.Http.Headers;
    using System.Text;
    using System.Threading.Tasks;
    using System.Web.Http;
    using Beginor.Owin.StaticFile;
    using Microsoft.AspNet.SignalR;
    using Microsoft.Owin;
    using Microsoft.Owin.Cors;
    using Owin;
     
    [assembly: OwinStartup(typeof(OwinTest2.server.Startup))]
    namespace OwinTest2.server
    {
        class Startup
        {
            // This code configures Web API. The Startup class is specified as a type
            // parameter in the WebApp.Start method.
            public void Configuration(IAppBuilder appBuilder)
            {
                // Configure Web API for self-host.
                HttpConfiguration config = new HttpConfiguration();
                config.Routes.MapHttpRoute(name: "DefaultApi",
                    routeTemplate: "api/{controller}/{action}/{id}", //{action}目的是为了一个Controller能有多个Get Post方法
                    defaults: new { id = RouteParameter.Optional });
                config.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
                config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
                appBuilder.UseWebApi(config);
     
                //静态文件托管
                appBuilder.Map("/page", map =>
                {
                    // 允许跨域
                    map.UseCors(CorsOptions.AllowAll);
                    map.UseStaticFile(new StaticFileMiddlewareOptions
                    {
                        RootDirectory = @"../Debug/page",
                        DefaultFile = "page/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托管
                appBuilder.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);
            }
        }
    }

LoginController 控制类(可用来处理异步请求):

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Net;
    using System.Net.Http;
    using System.Net.Http.Headers;
    using System.Text;
    using System.Threading.Tasks;
    using System.Web;
    using System.Web.Http;
     
    namespace OwinTest2.controllers
    {
        public class LoginController:ApiController
        {
            [HttpPost]
            public HttpResponseMessage login([FromBody]Obj obj)
            {
                StringBuilder msg = new StringBuilder();
                if (obj == null)
                {
                    msg.Append("参数不能为空");
                }
                else
                {
                    if (string.IsNullOrEmpty(obj.u_id))
                    {
                        msg.Append("u_id不能为空");
                    }
                    if (string.IsNullOrEmpty(obj.u_pwd))
                    {
                        msg.Append("u_pwd不能为空");
                    }
                }
                if (msg.Length > 0)
                {
                    msg.Insert(0, "error:");
                    return new HttpResponseMessage(HttpStatusCode.OK)
                    {
                        Content = new StringContent(msg.ToString(), System.Text.Encoding.UTF8)
                    };
                }
                //GlobalData.GetForm1().SetLog(obj.u_id + "----" + obj.u_pwd);
                //HttpResponseMessage result = null;
                //msg.Append("账号:" + obj.u_id + " 密码:" + obj.u_pwd);
                //result = new HttpResponseMessage(HttpStatusCode.OK)
                //{
                //    Content = new StringContent(msg.ToString(), System.Text.Encoding.UTF8)
                //};
                //return result;
     
                var httpResponseMessage = new HttpResponseMessage();
                //设置Cookie
                var cookie = new CookieHeaderValue("u_id", obj.u_id);
                cookie.Expires = DateTimeOffset.Now.AddDays(1);
                cookie.Domain = Request.RequestUri.Host;
                cookie.Path = "/";
                httpResponseMessage.Headers.AddCookies(new CookieHeaderValue[] { cookie });
                //返回index.html页面
                httpResponseMessage.Content = new StringContent(File.ReadAllText(@".\page\index.html"), Encoding.UTF8);
                //指定返回什么类型的数据
                httpResponseMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("text/html");
                
                return httpResponseMessage;
            }
     
            public class Obj
            {
                public string u_id { get; set; }
                public string u_pwd { get; set; }
            }
        }
    }

主要代码都在上面了,其他没放出来的无关紧要

访问地址:http://172.20.10.7:9000/page

客户端连接SignalR地址:http://172.20.10.7:9000/signalr

172.20.10.7这个ip根据你设置的来