在Windows服务中使用OWIN托管WebAPI

48

我使用OWIN(在Windows服务内部)自托管Web API。据我所知,这已足以使HTTP请求传达到Windows服务。我可以从本地(同一台计算机)访问WebAPI URL (http://localhost/users),但其他计算机无法访问。我使用的是端口80,IIS已停止。当IIS运行时,其他网站(在端口80上托管于IIS中)可以正常工作。

//在Windows服务中:

public partial class Service1 : ServiceBase
{
    ...
    ...

    protected override void OnStart(string[] args)
    {
        Console.WriteLine("Starting service...");
        string baseAddress = "http://localhost:80/";
        WebApp.Start<Startup>(baseAddress);  //This is OWIN stuff.
    }
    ...
    ...
}

public 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.
        var config = new HttpConfiguration();
        WebApiConfig.Register(config);
        appBuilder.UseWebApi(config);
    }
}

我需要做更多的事情才能使它在其他机器上运行吗?(我有一种感觉,传入的http请求没有被转发到Windows服务,而是仅转发到IIS。当您在本地访问时,可能不会通过侦听http请求的操作系统模块进行处理。这只是一个猜测。)


3
您可能会想查看这个示例GitHub项目:https://github.com/danesparza/OWIN-WebAPI-Service。 - Dan Esparza
2
仅供参考:像下面justmara的评论一样,你可以简单地从http://*:80/开始,这样它就会响应所有可用的地址。- justmara 2014年5月27日14:08 - Hoàng Long
我想知道如何将其投入生产,如果可能的话。那么,你如何将localhost:portNumber转换为真实主机名呢? - Weihui Guo
6个回答

59

您的机器防火墙可能会阻止传入请求。您可以执行以下操作:

运行wf.msc命令打开带有高级安全性的Windows防火墙,为TCP端口80添加一个新的入站规则。

(您应该注意到一些以World Wide Web Services...开头的入站规则。这些是为IIS准备的。我不确定启用这些规则是否足以使您的Windows服务接收请求......您可以尝试并查看是否有效,否则,如前所述,可以创建一个新的入站规则。)

更新:
根据您的评论,可能是因为您的Url注册而无法访问服务。以下是使用HttpListener注册多个url的示例。

StartOptions options = new StartOptions();
options.Urls.Add("http://localhost:9095");
options.Urls.Add("http://127.0.0.1:9095");
options.Urls.Add(string.Format("http://{0}:9095", Environment.MachineName));

using (WebApp.Start<Program>(options))
{

您可以在以下链接中了解有关URL注册的更多信息:
http://technet.microsoft.com/en-us/library/bb630429.aspx
http://technet.microsoft.com/en-us/library/bb677364.aspx


只需关闭防火墙以验证它是否是问题所在,如果解决了您的问题,则添加规则。 - 0leg
尝试了两种方式,都不起作用。http://localhost/users 可以工作,但是 http://127.0.0.1:80/users 或者 http://machine-name/users 不行。如果我使用端口80,会得到404未找到错误,如果我使用其他端口,会得到400错误 - 无效的请求主机名。这意味着什么? - Narayana
我家只有一台电脑。明天会检查并更新。 - Narayana
55
您可以将其启动在http://*:9095/,这样它将响应所有可用的地址。 - justmara
不错的回答,如果能包含使用 "netsh.exe" 配置 url/端口就更好了:https://msdn.microsoft.com/en-us/library/ms733768(v=vs.110).aspx(我认为另一个回答提到了 netsh) - peteski
显示剩余2条评论

20

在 Owin 服务中,有两件事情阻止你使用不同于 "localhost" 的内容:

  1. 应用程序需要以管理员身份运行,才能打开一个具有不同主机名的端口。你可以通过以管理员权限运行应用程序或使用以下命令为给定端口添加例外来解决这个问题:netsh http add urlacl url=http://*:9000/ user=<your user>
  2. Windows 防火墙可能会阻止来自其他计算机的流量。在我的情况下,防火墙没有阻止本地流量 (我可以访问 http://localhost:9000, http://127.0.0.1:9000, 或者 http://192.168.1.193:9000 - 这是我的本地 IP 地址,来自同一台计算机,但需要向防火墙添加端口例外,才能从另一台计算机访问到此服务)

谢谢你提供的以管理员权限运行的提示,那正是我的问题所在。 - mini998

6

我曾经遇到过类似的问题。以下解决方案适用于我。

StartOptions options = new StartOptions();
options.Urls.Add("http://localhost:9095");
options.Urls.Add("http://127.0.0.1:9095");
options.Urls.Add(string.Format("http://{0}:9095", Environment.MachineName));

using (WebApp.Start<Program>(options))
{
    ...
}

4
这是一个简单的疏忽,我也曾经遇到过:如果你只监听本地主机(localhost)、127.0.0.1等请求,那么别人就看不到它,因为只有你自己能够将其作为目标。在我的电脑上我是localhost,在任何端口上请求您的IP地址时,服务都会看到http://your_ip:80,而不是localhost。你只需要在"http://*:{0}"上提供服务,这样你可以通过onStart()传递端口信息。

1
类似问题。我编写了一个ServiceStack服务,并使用AppSelfHostBase实现将其托管在Windows服务中。注意:这是作为Net Core应用程序编写的,可以编译为控制台应用程序,但通过PeterKottas.DotNetCore.WindowsService(可通过NuGet获得)的魔法安装为Windows服务。
我将baseAddress设置为http://*.8088/并将其传递给我的AppSelfHostBase实现,但我只能从安装它的同一台机器访问该服务,并尝试在浏览器中打开元数据页面(http://[machine]:8088/api/metadata)时发现无法访问。解决方案是将我的控制台应用程序.exe文件添加到安装它的服务器上Windows防火墙允许的应用程序列表中。只需转到服务器上控制面板中的防火墙“允许的应用程序”对话框,单击“允许其他应用程序…”按钮,然后导航到Windows服务可执行文件即可。

Windows Firewall Allowed App dialog


我喜欢这个想法并尝试了一下,但它没有起作用,有什么建议吗? - user584018
你能给我一些细节吗? - Phoeniceus Agelaius
谢谢@Phoeniceus Agelaius,请在此新的讨论串中查看详情,https://stackoverflow.com/questions/61343301/hosting-webapi-using-owin-not-working-when-adding-the-add-the-firewall-allowed - user584018

1
最终对我有用的是这个值:

StartOptions options = new StartOptions();
options.Urls.Add("http://*:9095");

using (WebApp.Start<Program>(options))
{
    ...
}

请注意,在添加此项后,您只能在 Visual Studio 中使用管理员模式运行应用程序,并且发布版本的应用程序也需要以管理员模式运行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接