【问题标题】:Programmatically starting an HTTP server in C#?在 C# 中以编程方式启动 HTTP 服务器?
【发布时间】:2012-04-08 10:24:09
【问题描述】:

我是 C#、ASP.NET 新手。

假设我有一个现有的 C# 项目(来自“控制台应用程序”模板;我使用 Visual Studio)。我希望能够启动一个简单的 HTTP 服务器并提供 .aspx 页面(甚至是普通文本,在这种情况下我也在寻找一个不错的模板库 ^^),但 仅当通过命令行界面将某些命令提供给程序。 (因此,默认情况下服务器未启动。)

我怎样才能最好地做到这一点?

非常感谢您的帮助!

编辑:为了澄清,我希望将所有这些功能嵌入到单个非 webapp 非网站项目中。也就是说,该项目由三部分组成:命令行界面、可选运行的 Web 界面(HTTP 服务器)以及等待并响应任何一个请求的 core这两个接口。这是现有项目的当前状态,没有网络界面。

【问题讨论】:

  • 它应该为远程计算机提供页面,还是将 http 客户端驻留在同一台机器上?
  • 开发简单的 HTTP Server 不是问题,问题是服务于 .aspx 页面。
  • @Fredrik:它将同时服务于本地和远程计算机。我想通过创建一个新的 Web 应用程序项目来获取您所获得的功能,并以某种方式将其插入一个普通的命令行项目中。我怀疑这可能比我想象的更容易(?),但我是一个完整的新手。 @Baget:它甚至不必是 .aspx 页面。它可以是普通的 HTML。在那种情况下,我会去寻找某种模板库。
  • 您的目标平台是什么?换句话说,这是可以在服务器或台式机上运行的东西吗?如果是桌面,您认为会使用什么操作系统?
  • @Chris:这将在桌面系统上运行,很可能在 Windows XP 上运行。在这里,性能对我来说真的不重要。

标签: c# asp.net


【解决方案1】:

您可以在控制台应用程序中托管 ASP.NET 运行时。这是一个例子:

public class SimpleHost : MarshalByRefObject
{
    public void ProcessRequest(string page, string query, TextWriter writer)
    {
        SimpleWorkerRequest swr = new SimpleWorkerRequest(page, query, writer);
        HttpRuntime.ProcessRequest(swr);
    }
}

class Program
{
    static void Main(string[] args)
    {
        // TODO: Check to see if a given argument has been passed on the command-line

        SimpleHost host = (SimpleHost)ApplicationHost.CreateApplicationHost(
            typeof(SimpleHost), "/", Directory.GetCurrentDirectory());

        HttpListener listener = new HttpListener();
        listener.Prefixes.Add("http://localhost:9999/");
        listener.Start();
        Console.WriteLine("Listening for requests on http://localhost:9999/");

        while (true)
        {
            HttpListenerContext context = listener.GetContext();
            string page = context.Request.Url.LocalPath.Replace("/", "");
            string query = context.Request.Url.Query.Replace("?", "");
            using (var writer = new StreamWriter(context.Response.OutputStream))
            {
                host.ProcessRequest(page, query, writer);
            }
            context.Response.Close();
        }

    }
}

运行此程序时,您可能会收到TypeLoadException。您必须在当前目录中创建一个bin 子目录并将可执行文件的副本移至其中。这是因为 ASP.NET 运行时将查找 bin 子目录。另一种选择是将SimpleHost 放入一个单独的程序集中,然后将其部署到 GAC 中。

【讨论】:

  • 出于好奇,这会增加最大堆栈大小吗?在 IIS 7 中它只有 256K,而控制台应用程序 我认为 是 1MB,除非另有说明。
  • 感谢代码示例。我确实得到了 TypeLoadException。显然 System.Web 不包含 Hosting 命名空间。不过,我不明白一件事。我应该将哪个可执行文件放入bin 子目录?
  • 您是否引用了System.Web 程序集?至于您的问题,您需要将包含SimpleHost 类的可执行文件或程序集放在bin 子目录中。
  • 需要注意的是,HttpRuntime.ProcessRequest不一定会同步处理你传递的请求。如果您的服务器负载不足,它可能会将您传递的请求排入队列并处理已排队的先前请求。如果您在 ProcessRequest 调用之后关闭响应,则当请求最终得到服务并期望响应流打开时,这可能会产生许多异常。
【解决方案2】:

这是一篇很好的文章:http://msdn.microsoft.com/en-us/library/aa529311.aspx

关键是Microsoft.Web.Services3的用法

从链接文章复制的示例代码:

public partial class WindowsServiceToHostASMXWebService  : ServiceBase
{
    protected override void OnStart(string[] args)
    {
        Uri address = new Uri("soap.tcp://localhost/TestService");
        SoapReceivers.Add(new EndpointReference(address), typeof(Service ));
    }
    protected override void OnStop()
    {
        SoapReceivers.Clear();
    }
}

并调用它:

static void Main()
{
    System.ServiceProcess.ServiceBase[] ServicesToRun;
    // Change the following line to match.
    ServicesToRun = new System.ServiceProcess.ServiceBase[] { new WindowsServiceToHostASMXWebService() };
    System.ServiceProcess.ServiceBase.Run(ServicesToRun);
}

【讨论】:

    【解决方案3】:

    您可以使用“net”命令启动或停止服务,包括 IIS(Windows 上的 Web 服务器)使用的服务。

    确保已安装 IIS,并且您的站点像普通的 ASP.Net 站点一样工作。然后将“万维网发布”服务启动类型设置为手动而不是自动。现在您可以随时通过在控制台发出这样的命令来启动它(并通过Process.Start()从您的程序中):

    网络启动 w3svc

    现在,如果您想更多地将这个应用程序转储到任何旧计算机上,您会遇到一些问题。但是,如果该应用旨在帮助管理特定系统,那您就可以了。

    【讨论】:

      【解决方案4】:

      您可以使用 HttpRuntime 类。如果您需要,我可以提供一个简短的演示。

      【讨论】:

        猜你喜欢
        • 2018-10-07
        • 1970-01-01
        • 2011-10-03
        • 1970-01-01
        • 2019-07-15
        • 2019-01-14
        • 2017-10-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多